aperçu
dans cet article, nous allons introduire les concepts D’IoC (Inversion du contrôle) et DI (Injection de dépendance), et nous allons ensuite jeter un,
pour en savoir plus:
câblage au printemps: @Autowired, @Resource et @Inject
@Composante vs @Référentiel et @Service au Printemps
qu’Est-Ce que l’Inversion de Contrôle?,
L’Inversion de contrôle est un principe en génie logiciel par lequel le contrôle d’objets ou de parties d’un programme est transféré vers un conteneur ou un framework. Il est le plus souvent utilisé dans le contexte de la programmation orientée objet.
contrairement à la programmation traditionnelle, dans laquelle notre code personnalisé effectue des appels vers une bibliothèque, IoC permet à un framework de prendre le contrôle du flux d’un programme et d’effectuer des appels vers notre code personnalisé. Pour permettre cela, les frameworks utilisent des abstractions avec un comportement supplémentaire intégré., Si nous voulons ajouter notre propre comportement, nous devons étendre les classes du framework ou greffer nos propres classes.,
Les avantages de cette architecture sont les suivants:
- découpler l’exécution d’une tâche de son implémentation
- faciliter le basculement entre différentes implémentations
- plus grande modularité d’un programme
- plus grande facilité à tester un programme en isolant un composant ou en se moquant de ses dépendances et en permettant aux composants de communiquer via des contrats
L’Inversion du contrôle peut être obtenue grâce à divers mécanismes tels que: modèle de conception de stratégie, modèle de localisateur de Service, modèle d’usine et injection de dépendance (di).,
nous allons regarder DI ensuite.
Qu’est-ce que L’Injection de dépendance?
L’injection de dépendance est un modèle à travers lequel implémenter IoC, où le contrôle inversé est le réglage des dépendances de l’objet.
l’acte de connecter des objets avec d’autres objets, ou d ‘ « injecter” des objets dans d’autres objets, est effectué par un assembleur plutôt que par les objets eux-mêmes.,
Voici comment créer une dépendance d’objet dans la programmation traditionnelle:
public class Store { private Item item; public Store() { item = new ItemImpl1(); }}
dans l’exemple ci-dessus, nous devons instancier une implémentation de L’interface Item dans la classe Store elle-même.
en utilisant DI, nous pouvons réécrire L’exemple sans spécifier l’implémentation D’Item que nous voulons:
public class Store { private Item item; public Store(Item item) { this.item = item; }}
dans les sections suivantes, nous verrons comment nous pouvons fournir L’implémentation D’Item via des métadonnées.,
IoC et DI sont des concepts simples, mais ont des implications profondes dans la façon dont nous structurons nos systèmes, ils méritent donc d’être bien compris.
Le Printemps Conteneur IoC
Un conteneur IoC est une caractéristique commune des cadres qui mettent en œuvre des Cio.
dans le framework Spring, le conteneur IoC est représenté par L’interface ApplicationContext. Le conteneur Spring est responsable de l’instanciation, de la configuration et de l’assemblage des objets appelés beans, ainsi que de la gestion de leur cycle de vie.,
le framework Spring fournit plusieurs implémentations de L’interface ApplicationContext — ClassPathXmlApplicationContext et FileSystemXmlApplicationContext pour les applications autonomes, et WebApplicationContext pour les applications web.
pour assembler des beans, le conteneur utilise des métadonnées de configuration, qui peuvent être sous forme de configuration XML ou d’annotations.
Voici une façon d’instancier manuellement un conteneur:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Pour définir l’attribut d’élément dans l’exemple ci-dessus, nous pouvons utiliser les métadonnées., Ensuite, le conteneur Lira ces métadonnées et les utilisera pour assembler des beans lors de l’exécution.
L’Injection de dépendance dans Spring peut être effectuée via des constructeurs, des setters ou des champs.
injection de dépendance basée sur le constructeur
dans le cas de l’injection de dépendance basée sur le constructeur, le conteneur invoquera un constructeur avec des arguments représentant chacun une dépendance que nous voulons définir.
Spring résout chaque argument principalement par type, suivi du nom de l’attribut et de l’index pour la désambiguïsation., Voyons la configuration d’un bean et de ses dépendances à l’aide d’annotations:
L’annotation @Configuration indique que la classe est une source de définitions de bean. Aussi, nous pouvons l’ajouter à plusieurs classes de configuration.
L’annotation @Bean est utilisée sur une méthode pour définir un bean. Si nous ne spécifions pas de nom personnalisé, le nom du bean sera par défaut le nom de la méthode.
pour un bean avec la portée singleton par défaut, Spring vérifie d’abord si une instance mise en cache du bean existe déjà et n’en crée une nouvelle que si ce n’est pas le cas., Si nous utilisons la portée du prototype, le conteneur renvoie une nouvelle instance de bean pour chaque appel de méthode.
Une autre façon de créer la configuration des beans est via la configuration XML:
injection de dépendance basée sur Setter
Pour DI basé sur setter, le conteneur appellera les méthodes setter de notre classe, après avoir appelé un constructeur sans argument ou une méthode d’usine statique sans argument pour instancier le bean., Créons cette configuration en utilisant des annotations:
@Beanpublic Store store() { Store store = new Store(); store.setItem(item1()); return store;}
Nous pouvons également utiliser XML pour la même configuration de beans:
<bean class="org.baeldung.store.Store"> <property name="item" ref="item1" /></bean>
Les types D’injection basés sur le constructeur et le setter peuvent être combinés pour le même bean. La documentation Spring recommande d’utiliser l’injection basée sur le constructeur pour les dépendances obligatoires et l’injection basée sur le setter pour les dépendances facultatives.
7., Injection de dépendance basée sur le champ
en cas de DI basée sur le champ, nous pouvons injecter les dépendances en les marquant avec une annotation @Autowired:
public class Store { @Autowired private Item item; }
lors de la construction de L’objet Store, s’il n’y a pas de méthode constructeur ou setter pour injecter le bean
Nous pouvons également y parvenir en utilisant la configuration XML.,
cette approche peut sembler plus simple et plus propre, mais elle n’est pas recommandée car elle présente quelques inconvénients tels que:
- cette méthode utilise la réflexion pour injecter les dépendances, ce qui est plus coûteux que l’injection basée sur un constructeur ou un setter
- Il est vraiment facile de continuer à ajouter plusieurs dépendances Si vous utilisiez l’injection de constructeur, avoir plusieurs arguments nous aurait fait penser que la classe fait plus d’une chose qui peut violer le principe de Responsabilité Unique.,
Plus d’informations sur l’annotation @Autowired peuvent être trouvées dans L’article câblage dans Spring.
autowiring Dependencies
Le câblage permet au conteneur Spring de résoudre automatiquement les dépendances entre les beans collaborateurs en inspectant les beans qui ont été définis.,
Il existe quatre modes d’autowiring d’un bean en utilisant une configuration XML:
- no: la valeur par défaut – cela signifie qu’aucun autowiring n’est utilisé pour le bean et que nous devons nommer explicitement les dépendances
- byName: autowiring se fait en fonction du nom de la propriété, donc Spring recherchera un bean avec le même nom que type de la propriété. Cela signifie que Spring recherchera un haricot avec le même type de propriété à définir., S’il y a plus d’un bean de ce type, le framework lève une exception.,peut également injecter des beans en utilisant l’annotation @Autowired pour autowiring par type:
public class Store { @Autowired private Item item;}
S’il y a plus d’un bean du même type, nous pouvons utiliser l’annotation @Qualifier pour référencer un bean par nom:
public class Store { @Autowired @Qualifier("item1") private Item item;}
maintenant, autowire beans par type Via ID= »408ab5c2d2″>
ensuite, injectons un bean nommé item dans la propriété Item du bean Store par son nom via XML:
<bean class="org.baeldung.store.ItemImpl1" /><bean class="org.baeldung.store.Store" autowire="byName"></bean>
Nous pouvons également remplacer l’autowiring en définissant explicitement les dépendances via des arguments de constructeur ou des setters.,
Paresseux Initialisé Haricots
Par défaut, le conteneur crée et configure tous singleton haricots pendant l’initialisation. Pour éviter cela, vous pouvez utiliser l’attribut lazy-init avec la valeur true sur la configuration du bean:
<bean class="org.baeldung.store.ItemImpl1" lazy-init="true" />
En conséquence, le bean item1 ne sera initialisé que lors de sa première demande, et non au démarrage., L’avantage de ceci est un temps d’initialisation plus rapide, mais le compromis est que les erreurs de configuration ne peuvent être découvertes qu’après la demande du bean, ce qui peut prendre plusieurs heures, voire plusieurs jours après l’exécution de l’application.
Conclusion
dans cet article, nous avons présenté les concepts d’inversion de contrôle et d’injection de dépendance et les avons illustrés dans le cadre Spring.
Vous pouvez en savoir plus sur ces concepts dans les articles de Martin Fowler:
- Inversion des conteneurs de contrôle et modèle d’Injection de dépendance.,
- l’Inversion de Contrôle