Premièrement, et le plus important - tous les beans Spring sont gérés - ils "vivent" à l'intérieur d'un conteneur, appelé "contexte d'application".
Deuxièmement, chaque application a un point d'entrée vers ce contexte. Les applications Web ont un Servlet, JSF utilise un el-resolver, etc. De plus, il y a un endroit où le contexte de l'application est démarré et tous les beans - câblés automatiquement. Dans les applications Web, cela peut être un écouteur de démarrage.
Le câblage automatique se produit en plaçant une instance d'un bean dans le champ souhaité dans une instance d'un autre bean. Les deux classes doivent être des beans, c'est-à-dire qu'elles doivent être définies pour vivre dans le contexte de l'application.
Qu'est-ce que «vivre» dans le contexte de l'application? Cela signifie que le contexte instancie les objets, pas vous. C'est-à-dire - vous ne faites jamais new UserServiceImpl()
- le conteneur trouve chaque point d'injection et y définit une instance.
Dans vos contrôleurs, vous avez juste les éléments suivants:
@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {
// Tells the application context to inject an instance of UserService here
@Autowired
private UserService userService;
@RequestMapping("/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
// The UserServiceImpl is already injected and you can use it
userService.login(username, password);
}
}
Quelques notes:
- Dans votre
applicationContext.xml
vous devez activer la <context:component-scan>
sorte que les classes sont scannés pour le @Controller
, @Service
etc. annotations.
- Le point d'entrée pour une application Spring-MVC est le DispatcherServlet, mais il vous est caché, et donc l'interaction directe et l'amorçage du contexte d'application se produisent derrière la scène.
UserServiceImpl
doit également être défini comme bean - en utilisant <bean id=".." class="..">
ou en utilisant l' @Service
annotation. Puisqu'il sera le seul implémenteur de UserService
, il sera injecté.
- Outre l'
@Autowired
annotation, Spring peut utiliser le câblage automatique configurable en XML. Dans ce cas, tous les champs dont le nom ou le type correspond à un bean existant obtiennent automatiquement un bean injecté. En fait, c'était l'idée initiale du câblage automatique - avoir des champs injectés avec des dépendances sans aucune configuration. D'autres annotations comme @Inject
, @Resource
peuvent également être utilisées.
Dépend si vous voulez la route des annotations ou la route de définition XML du bean.
Supposons que vous ayez défini les beans dans votre
applicationContext.xml
:Le câblage automatique se produit au démarrage de l'application. Donc, dans
fooController
, qui, pour des raisons d'argument, veut utiliser laUserServiceImpl
classe, vous l'annoteriez comme suit:Lorsqu'il le verra
@Autowired
, Spring recherchera une classe qui correspond à la propriété dans leapplicationContext
, et l'injectera automatiquement. Si vous avez plus d'unUserService
bean, alors vous devrez qualifier celui qu'il doit utiliser.Si vous procédez comme suit:
Il ne ramassera pas le
@Autowired
sauf si vous le définissez vous-même.la source
bean id
dansapplicationContext.xml
. Nous devrons définir lauserService
variable avecUserService
type. Alors pourquoi faire une entrée dans lexml
fichier.@Autowired
est une annotation introduite dans Spring 2.5 et utilisée uniquement pour l'injection.Par exemple:
la source
@Autowired
ne signifie pas que "vous pouvez utiliser toutes les fonctions (méthodes) et variables enB
classe depuis la classeA
". Ce qu'il fait, c'est apporter une instance deA
dans des instances deB
, donc vous pouvez le faire àa.getId()
partir deB
.Comment
@Autowired
fonctionne en interne?Exemple:
fichier .xml, il se ressemblera s'il n'utilise pas
@Autowired
:Si vous utilisez
@Autowired
alors:fichier .xml, il se ressemblera s'il n'utilise pas
@Autowired
:Si vous avez encore des doutes, passez en dessous de la démo en direct
Comment fonctionne @Autowired en interne?
la source
Il vous suffit d'annoter votre classe de service
UserServiceImpl
avec une annotation:Le conteneur à ressort prendra en charge le cycle de vie de cette classe lors de son enregistrement en tant que service.
Ensuite, dans votre contrôleur, vous pouvez le câbler automatiquement (instancier) et utiliser ses fonctionnalités:
la source
L'injection de dépendance Spring vous aide à supprimer le couplage de vos classes. Au lieu de créer un objet comme celui-ci:
Vous l'utiliserez après avoir introduit DI:
Pour cela, vous devez créer un bean de votre service dans votre
ServiceConfiguration
fichier. Après cela, vous devez importer cetteServiceConfiguration
classe dans votreWebApplicationConfiguration
classe afin de pouvoir câbler automatiquement ce bean dans votre Controller comme ceci:Vous pouvez trouver un exemple de POC basé sur la configuration java .
la source
Manière standard:
Interface de service utilisateur:
Classe UserServiceImpl:
Production:
Example test UserServiceImpl
C'est un excellent exemple de classes couplées serrées, un mauvais exemple de conception et il y aura des problèmes avec les tests (PowerMockito est également mauvais).
Jetons maintenant un coup d'œil à l'injection de dépendance SpringBoot, un bel exemple de couplage lâche:
L'interface reste la même,
Classe principale:
Classe ServiceUserImpl:
Production:
Example test UserServiceImpl
et maintenant il est facile d'écrire le test:
J'ai montré une
@Autowired
annotation sur le constructeur mais elle peut également être utilisée sur le setter ou sur le terrain.la source
Le concept entier d'inversion de contrôle signifie que vous êtes libre d'une corvée pour instancier des objets manuellement et fournir toutes les dépendances nécessaires. Lorsque vous annotez une classe avec une annotation appropriée (par exemple
@Service
), Spring instanciera automatiquement l'objet pour vous. Si vous n'êtes pas familier avec les annotations, vous pouvez également utiliser un fichier XML à la place. Cependant, ce n'est pas une mauvaise idée d'instancier les classes manuellement (avec lenew
mot - clé) dans les tests unitaires lorsque vous ne voulez pas charger le contexte Spring entier.la source
Gardez à l'esprit que vous devez activer l'
@Autowired
annotation en ajoutant un élément<context:annotation-config/>
dans le fichier de configuration Spring. Cela enregistrera leAutowiredAnnotationBeanPostProcessor
qui prend en charge le traitement des annotations.Et puis, vous pouvez câbler automatiquement votre service en utilisant la méthode d'injection sur le terrain.
J'ai trouvé cela dans l' annotation Spring @autowired
la source
Il existe 3 façons de créer une instance à l'aide de
@Autowired
.1.
@Autowired
sur les propriétésL'annotation peut être utilisée directement sur les propriétés, éliminant ainsi le besoin de getters et setters:
Dans l'exemple ci-dessus, Spring recherche et injecte
userService
quandUserController
est créé.2.
@Autowired
sur les SettersL'
@Autowired
annotation peut être utilisée sur les méthodes de définition. Dans l'exemple ci-dessous, lorsque l'annotation est utilisée sur la méthode setter, la méthode setter est appelée avec l'instance deuserService
whenUserController
est créée:3.
@Autowired
sur les constructeursL'
@Autowired
annotation peut également être utilisée sur les constructeurs. Dans l'exemple ci-dessous, lorsque l'annotation est utilisée sur un constructeur, une instance deuserService
est injectée en tant qu'argument au constructeur lors de saUserController
création:la source
En termes simples Autowiring, le câblage des liens automatiquement, vient maintenant la question de savoir qui fait cela et quel type de câblage. La réponse est: le conteneur fait cela et le type de câblage secondaire est pris en charge, les primitives doivent être effectuées manuellement.
Question: Comment le conteneur sait-il quel type de câblage?
Réponse: Nous le définissons comme byType, byName, constructeur.
Question: Existe-t-il un moyen de ne pas définir le type de câblage automatique?
Réponse: Oui, il est là en faisant une annotation, @Autowired.
Question: Mais comment le système sait-il que je dois choisir ce type de données secondaires?
Réponse: Vous fournirez ces données dans votre fichier spring.xml ou en utilisant des annotations de stéréotypes à votre classe afin que le conteneur puisse lui-même créer les objets pour vous.
la source