J'apprends Spring 3 et je ne semble pas saisir la fonctionnalité derrière <context:annotation-config>
et <context:component-scan>
.
D'après ce que je l' ai lu , ils semblent gérer différentes annotations ( @Required
, @Autowired
etc vs @Component
, @Repository
, @Service
etc.), mais aussi de ce que j'ai lu , ils enregistrent le même processeur post haricots classes.
Pour me confondre encore plus, il y a un annotation-config
attribut sur <context:component-scan>
.
Quelqu'un peut-il faire la lumière sur ces étiquettes? Qu'est-ce qui est similaire, ce qui est différent, est-ce que l'un est remplacé par l'autre, ils se complètent, ai-je besoin de l'un d'eux, des deux?
java
spring
configuration
annotations
spring-3
user938214097
la source
la source
component-scan
autant que possible.Réponses:
<context:annotation-config>
est utilisé pour activer les annotations dans les beans déjà enregistrés dans le contexte de l'application (peu importe s'ils ont été définis avec XML ou par analyse de package).<context:component-scan>
peut également faire ce qu'il<context:annotation-config>
fait mais<context:component-scan>
analyse également les packages pour trouver et enregistrer des beans dans le contexte de l'application.Je vais utiliser quelques exemples pour montrer les différences / similitudes.
Commençons par une configuration de base de trois grains de type
A
,B
etC
, avecB
etC
injecté dansA
.Avec la configuration XML suivante:
Le chargement du contexte produit la sortie suivante:
OK, c'est la sortie attendue. Mais c'est le printemps "à l'ancienne". Maintenant que nous avons des annotations, utilisons-les pour simplifier le XML.
Tout d'abord, permet de câbler automatiquement les propriétés
bbb
etccc
sur le beanA
comme ceci:Cela me permet de supprimer les lignes suivantes du XML:
Mon XML est maintenant simplifié à ceci:
Lorsque je charge le contexte, j'obtiens la sortie suivante:
OK, c'est faux! Qu'est-il arrivé? Pourquoi mes propriétés ne sont-elles pas câblées automatiquement?
Eh bien, les annotations sont une fonctionnalité intéressante, mais en elles-mêmes, elles ne font absolument rien. Ils annotent juste des trucs. Vous avez besoin d'un outil de traitement pour trouver les annotations et faire quelque chose avec elles.
<context:annotation-config>
à la rescousse. Cela active les actions pour les annotations qu'il trouve sur les beans définis dans le même contexte d'application où lui-même est défini.Si je change mon XML en ceci:
lorsque je charge le contexte de l'application, j'obtiens le bon résultat:
OK, c'est bien, mais j'ai supprimé deux lignes du XML et j'en ai ajouté une. Ce n'est pas une très grande différence. L'idée avec des annotations est qu'il est censé supprimer le XML.
Supprimons donc les définitions XML et remplaçons-les toutes par des annotations:
Dans le XML, nous ne gardons que ceci:
Nous chargeons le contexte et le résultat est ... Rien. Aucun bean n'est créé, aucun bean n'est câblé automatiquement. Rien!
En effet, comme je l'ai dit dans le premier paragraphe, les
<context:annotation-config />
seuls travaux sur les beans enregistrés dans le contexte de l'application. Parce que j'ai supprimé la configuration XML pour les trois beans, aucun bean n'a été créé et<context:annotation-config />
n'a pas de "cibles" sur lesquelles travailler.Mais ce ne sera pas un problème pour
<context:component-scan>
lequel peut analyser un package pour les "cibles" sur lesquelles travailler. Modifions le contenu de la configuration XML dans l'entrée suivante:Lorsque je charge le contexte, j'obtiens la sortie suivante:
Hmmmm ... il manque quelque chose. Pourquoi?
Si vous regardez de près les classes, la classe
A
a un package,com.yyy
mais j'ai spécifié dans le<context:component-scan>
package à utiliser,com.xxx
donc cela a complètement manqué maA
classe et n'a repris queB
etC
qui sont sur lecom.xxx
package.Pour résoudre ce problème, j'ajoute également cet autre package:
et maintenant nous obtenons le résultat attendu:
Et c'est tout! Maintenant, vous n'avez plus de définitions XML, vous avez des annotations.
Comme dernier exemple, en gardant les classes annotées
A
,B
etC
et en ajoutant ce qui suit au XML, ce que nous obtiendrons après le chargement du contexte?Nous obtenons toujours le bon résultat:
Même si le bean pour la classe
A
n'est pas obtenu par l'analyse, les outils de traitement sont toujours appliqués par<context:component-scan>
sur tous les beans enregistrés dans le contexte de l'application, même pourA
qui ont été enregistrés manuellement dans le XML.Mais que se passe-t-il si nous avons le XML suivant, obtiendrons-nous des beans dupliqués parce que nous avons spécifié les deux
<context:annotation-config />
et<context:component-scan>
?Non, pas de doublons, nous obtenons à nouveau le résultat attendu:
En effet, les deux balises enregistrent les mêmes outils de traitement (
<context:annotation-config />
peuvent être omis si<context:component-scan>
spécifié), mais Spring se charge de les exécuter une seule fois.Même si vous enregistrez vous-même les outils de traitement plusieurs fois, Spring s'assurera qu'ils ne font leur magie qu'une seule fois; ce XML:
générera toujours le résultat suivant:
OK, ça parle de ça.
J'espère que ces informations ainsi que les réponses de @Tomasz Nurkiewicz et @Sean Patrick Floyd sont tout ce dont vous avez besoin pour comprendre comment
<context:annotation-config>
et<context:component-scan>
travailler.la source
J'ai trouvé ce joli résumé dont les annotations sont captées par quelles déclarations. En l'étudiant, vous constaterez que
<context:component-scan/>
reconnaît un surensemble d'annotations reconnu par<context:annotation-config/>
, à savoir:@Component
,@Service
,@Repository
,@Controller
,@Endpoint
@Configuration
,@Bean
,@Lazy
,@Scope
,@Order
,@Primary
,@Profile
,@DependsOn
,@Import
,@ImportResource
Comme vous pouvez le voir, il s’étend
<context:component-scan/>
logiquement avec l’analyse des composants CLASSPATH et les fonctionnalités Java @Configuration.<context:annotation-config/>
la source
Le printemps vous permet de faire deux choses:
1. Câblage automatique
Habituellement, dans applicationContext.xml, vous définissez les beans et les autres beans sont câblés à l'aide de méthodes de constructeur ou de définition. Vous pouvez câbler des beans à l'aide de XML ou d'annotations. Si vous utilisez des annotations, vous devez activer les annotations et vous devez ajouter
<context:annotation-config />
dans applicationContext.xml . Cela simplifiera la structure de la balise de applicationContext.xml , car vous n'aurez pas à câbler manuellement les beans (constructeur ou setter). Vous pouvez utiliser des@Autowire
annotations et les beans seront câblés par type.Un pas en avant pour échapper à la configuration XML manuelle est
2. Découverte
automatique La découverte automatique simplifie le XML encore plus loin, dans le sens où vous n'avez même pas besoin d'ajouter la
<bean>
balise dans applicationContext.xml . Vous marquez simplement les beans spécifiques avec l'une des annotations suivantes et Spring connectera automatiquement les beans marqués et leurs dépendances au conteneur Spring. Les annotations sont les suivantes: @Controller , @Service , @Component , @Repository . En utilisant<context:component-scan>
et en pointant le package de base, Spring détecte automatiquement et connecte les composants dans le conteneur Spring.Comme conclusion:
<context:annotation-config />
est utilisé pour pouvoir utiliser l' annotation @Autowired<context:component-scan />
est utilisé pour déterminer la recherche de beans spécifiques et la tentative de câblage automatique.la source
<context:annotation-config>
active de nombreuses annotations différentes dans les beans, qu'elles soient définies en XML ou via l'analyse des composants.<context:component-scan>
sert à définir des beans sans utiliser XMLPour plus d'informations, lisez:
la source
<context:component-scan>
je ne pourrai pas remplacer la définition de bean en utilisant XML?<context:component-scan>
? Dois-je perdre quelque chose si je n'utilise pas le<context:annotation-config>
?La différence entre les deux est vraiment simple!.
Vous permet d'utiliser des annotations limitées au câblage des propriétés et des constructeurs uniquement de beans!.
Tandis que
Permet tout ce qui
<context:annotation-config />
peut faire, avec addition d'utiliser les stéréotypes par exemple ..@Component
,@Service
,@Repository
. Vous pouvez donc câbler des beans entiers et pas seulement restreints aux constructeurs ou aux propriétés!.la source
<context:annotation-config>
: Analyse et activation des annotations pour les beans déjà enregistrés dans Spring Config XML.<context:component-scan>
: Enregistrement Bean +<context:annotation-config>
@Autowired et @Required sont des propriétés de niveau cible, donc le bean doit s'enregistrer au printemps IOC avant d'utiliser ces annotations. Pour activer ces annotations, vous devez enregistrer les beans respectifs ou les inclure
<context:annotation-config />
. c'est à dire ne<context:annotation-config />
fonctionne qu'avec des beans enregistrés.@Required active l'
RequiredAnnotationBeanPostProcessor
outil de traitement@Autowired active l'
AutowiredAnnotationBeanPostProcessor
outil de traitementRemarque: L' annotation elle-même n'a rien à faire, nous avons besoin d'un outil de traitement , qui est une classe en dessous, responsable du processus principal.
@Repository, @Service et @Controller sont @Component et ciblent le niveau de classe .
<context:component-scan>
il scanne le paquet et trouve et enregistre les beans, et il inclut le travail effectué par<context:annotation-config />
.Migration de XML vers des annotations
la source
La
<context:annotation-config>
balise indique à Spring d'analyser la base de code pour résoudre automatiquement les exigences de dépendance des classes contenant l'annotation @Autowired.Spring 2.5 ajoute également la prise en charge des annotations JSR-250 telles que @Resource, @PostConstruct et @ PreDestroy. L'utilisation de ces annotations nécessite également que certains BeanPostProcessors soient enregistrés dans le conteneur Spring. Comme toujours, ceux-ci peuvent être enregistrés en tant que définitions de haricots individuels, mais ils peuvent également être implicitement enregistrés en incluant
<context:annotation-config>
balise dans la configuration du ressort.Tiré de la documentation Spring de la configuration basée sur les annotations
Spring offre la capacité de détecter automatiquement les classes «stéréotypées» et d'enregistrer les BeanDefinitions correspondantes avec ApplicationContext.
Selon javadoc de org.springframework.stereotype :
Les stéréotypes sont des annotations indiquant les rôles des types ou des méthodes dans l'architecture globale (à un niveau conceptuel plutôt que d'implémentation). Exemple: @Controller @Service @Repository etc. Ceux-ci sont destinés à être utilisés par des outils et des aspects (faisant une cible idéale pour les coupes de points).
Pour détecter automatiquement ces classes de «stéréotypes», une
<context:component-scan>
balise est requise.La
<context:component-scan>
balise indique également à Spring d'analyser le code des beans injectables sous le package (et tous ses sous-packages) spécifié.la source
Ne résout que les annotations
@Autowired
et@Qualifer
, c'est tout, il s'agit de l' injection de dépendance , il y a d'autres annotations qui font le même travail, je pense comment@Inject
, mais tout sur le point de résoudre DI via des annotations.Attention, même lorsque vous avez déclaré l'
<context:annotation-config>
élément, vous devez quand même déclarer votre classe comment un Bean, rappelez-vous que nous avons trois options<bean>
Maintenant avec
Cela fait deux choses:
<context:annotation-config>
.Par conséquent, si vous déclarez
<context:component-scan>
, il n'est plus nécessaire de déclarer<context:annotation-config>
aussi.C'est tout
Un scénario courant était par exemple de déclarer uniquement un bean via XML et de résoudre le DI via des annotations, par exemple
Nous avons seulement déclaré les beans, rien à propos de
<constructor-arg>
et<property>
, la DI est configurée dans leurs propres classes via @Autowired. Cela signifie que les services utilisent @Autowired pour leurs composants de référentiels et que les référentiels utilisent @Autowired pour les composants JdbcTemplate, DataSource, etc.la source
essayez avec
<context:component-scan base-package="..." annotation-config="false"/>
, dans votre configuration @Service, @Repository, @Component fonctionne très bien, mais @ Autowired, @ Resource et @Inject ne fonctionne pas.Cela signifie que AutowiredAnnotationBeanPostProcessor ne sera pas activé et que le conteneur Spring ne traitera pas les annotations de câblage automatique.
la source
L'autre point important à noter est qu'il
context:component-scan
appelle implicitement lecontext:annotation-config
pour activer les annotations sur les beans. Eh bien, si vous ne voulezcontext:component-scan
pas activer implicitement les annotations pour vous, vous pouvez continuer à définir l'élément annotation-config ducontext:component-scan
tofalse
.Résumer:
la source
<context:component-scan base-package="package name" />
:Ceci est utilisé pour indiquer au conteneur qu'il y a des classes de bean dans mon package qui analysent ces classes de bean. Afin d'analyser les classes de bean par conteneur au-dessus du bean, nous devons écrire l'une des annotations de type stéréo comme suit.
@Component
,@Service
,@Repository
,@Controller
<context:annotation-config />
:Si nous ne voulons pas écrire explicitement la balise du bean en XML, alors comment le conteneur sait s'il y a un câblage automatique dans le bean. Cela est possible en utilisant l'
@Autowired
annotation. nous devons informer le conteneur qu'il y a un câblage automatique dans mon haricotcontext:annotation-config
.la source
Une
<context:component-scan/>
balise personnalisée enregistre le même ensemble de définitions de bean que celui utilisé par, en dehors de sa responsabilité principale d'analyser les packages java et d'enregistrer les définitions de bean à partir du chemin de classe.Si, pour une raison quelconque, cet enregistrement des définitions de bean par défaut doit être évité, la manière de le faire consiste à spécifier un attribut supplémentaire "annotation-config" dans le composant-scan, de cette façon:
Référence: http://www.java-allandsundry.com/2012/12/contextcomponent-scan-contextannotation.html
la source
<context:annotation-config>
:Cela indique à Spring que je vais utiliser des beans annotés comme Spring Bean et ceux-ci seront câblés via des
@Autowired
annotations, au lieu de déclarer dans le fichier xml de config de Spring.<context:component-scan base-package="com.test...">
:Cela indique au conteneur Spring où commencer la recherche de ces beans annotés. Ici, le printemps recherchera tous les sous-packages du package de base.
la source
vous pouvez trouver plus d'informations dans le fichier de schéma de contexte de printemps. ce qui suit est dans spring-context-4.3.xsd
la source
En complément, vous pouvez utiliser
@ComponentScan
pour utiliser<context:component-scan>
de manière annotée.Il est également décrit au printemps.io
Une chose à noter, si vous utilisez Spring Boot, la @Configuration et @ComponentScan peuvent être implicites en utilisant l'annotation @SpringBootApplication.
la source