J'essaie de comprendre l'annotation @Autowired. Je l'ai lu, mais cela n'a toujours pas beaucoup de sens pour moi
Le cas spécifique que je recherche est de passer un référentiel dans une classe de micro-service
Pourquoi le faisons-nous
public SomeClass (Repo repo) { this.repo = repo; }
au lieu de simplement faire
@Autowired public SomeClass (Repo repo) { this.repo = repo; }
4 Réponses :
Lorsque vous avez plusieurs constructeurs, vous devez indiquer à spring quel constructeur utiliser. Inutile la plupart du temps.
Vérifiez ici: https://www.baeldung.com/constructor-injection- au printemps
Depuis le printemps 4.3, les classes avec un seul constructeur peuvent omettre Annotation @Autowired. Un petit peu de commodité et retrait passe-partout!
Il n'y a qu'un seul constructeur dans la classe que je regarde
Vous avez raison. Les conteneurs DI, comme Spring, sont destinés à découpler les composants les uns des autres, en adhérant au Principe d'inversion de dépendance (DIP). De ce point de vue, il est plutôt gênant - c'est le moins qu'on puisse dire - que votre conteneur DI vous oblige à appliquer ces attributs spécifiques à la bibliothèque à vos classes. Cela introduit à nouveau un couplage serré - ce que nous travaillons si dur pour éviter. Cela force également un verrouillage du fournisseur. Tout votre code d'application dépend désormais de cet outil externe. Ceci est une violation du DIP.
À la place, lorsque vos composants d'application ont un constructeur public unique , qui est une bonne pratique , il ne devrait pas être nécessaire de définir un tel attribut sur la classe. Dans ce cas, le constructeur de la classe déclare sans ambiguïté ses dépendances requises. Tout bon conteneur DI devrait être capable de composer un graphe d'objets basé sur les informations de type statique fournies par ce constructeur unique.
Si je ne me trompe pas, les nouvelles versions de Spring vous permettent d'omettre l'attribut.
Vous pouvez faire ceci:
public SomeClass (Repo repo) { this.repo = repo; }
si vous prévoyez d'instancier votre objet vous-même.
Mais puisque vous voulez que le conteneur instancie vos objets (beans), vous lui demandez d'injecter votre dépendance Repo
lors de la création du bean SomeClass
. Vous faites cela en ajoutant @Autowired
au-dessus de votre constructeur.
Vous pouvez également faire ceci (injection de champ):
@Component @RequiredArgConstructor public class SomeClass { private final Repo repo; }
Mais pour faciliter les tests unitaires, l'injection de constructeur est préférable.
Notez que depuis le printemps 4.3, @Autowired
n'est plus nécessaire sur le constructeur.
EDIT
Mieux, lorsque vous utilisez Lombok
vous pouvez faire ceci:
@Component public class SomeClass { @Autowired private Repo repo; }
Lombok générera le constructeur
public SomeClass (Repo repo) { this.repo = repo; }
pour vous et le container va injecter la dépendance.
Mais nous avons une classe de test qui instancie explicitement la classe Repo, puis passe l'objet Repo dans la classe Micro-Service ("SomeClass"). Est-ce donc incorrect?
Cela dépend du type de test que vous effectuez. Pour le test unitaire, ce n'est pas correct, vous devez vous moquer de la dépendance repo
. Pour le test d'intégration, cela peut être correct, mais puisque vous utilisez Spring, laissez Spring gérer votre dépendance (sauf pour les tests unitaires).
L'annotation @Autowired utilisera automatiquement un 'Bean' (ressource gérée par spring) de type Repo à partir du contexte d'application s'il en existe un. Si votre méthode SomeClass est elle-même un 'Bean' (annoté avec @Component, @Service ou @Repository), spring s'assurera qu'un bean de type Repo existe dans le contexte de l'application avant d'instancier votre bean SomeClass.
Cet article est utile: https://www.baeldung.com/spring-autowire
Comme d'autres sur ce fil l'ont mentionné, l'injection de constructeur facilite les tests unitaires. Une façon de contourner ce problème est de créer une classe statique annotée avec @TestConfiguration qui contient les beans dont vous avez besoin pour votre contexte de test.
Cet article contient quelques informations à ce sujet: https://www.baeldung.com/spring -boot-testing
Le site Baeldung est une excellente ressource si vous êtes nouveau au printemps.