Selon Spring Doc-
Configure les directives d'analyse des composants à utiliser avec les classes @Configuration. Fournit une prise en charge parallèle avec l'élément
<context:component-scan>
de Spring XML.
Dans mon application Web printanière, il existe plusieurs fichiers portant la mention @Configuration
, afin d’enregistrer le bean @component
dans un conteneur printanier-
Question1- Peut-on utiliser @ComponentScan
dans n'importe quel de la classe @Configuration
ou dans toutes les classes@Configuration
?
Question 2-
J'ai aussi vu au printemps doc
@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
}
Pourquoi ici analyser la classe de configuration elle-même.
edit: Fondamentalement, ma compréhension de @ComponentScan
est de scanner et d’enregistrer un bean de type stéréo (ex-@componant
, @Controller
, @Services
etc.), pourquoi nous enregistrons @Configuration
Bean.
Pour votre question 1 -
oui, vous pouvez enregistrer un bean à l'aide de @ComponentScan
dans l'un des bean configuration qui est enregistré dans le conteneur spring . Vous pouvez enregistrer un bean dans un conteneur de l'une des manières suivantes -
@Configuration
dans rootcontext
ou dispatchersevletcontext
.@Configuration
dans un bean déjà enregistréin conteneur.Disons que vous avez la classe MvcConfig
dans laquelle vous analysez des composants
@ComponentScan(basePackages = {"xxxx","yyyy","zzzz"})
@Configuration
public class MvcConfig {
....
}
Pour enregistrer MvcConfig
dans un conteneur, vous devez faire
Non plus
new AnnotationConfigWebApplicationContext().register(MvcConfig.class);
Ou
new AnnotationConfigWebApplicationContext().register(AnotherConfig.class);
@Configuration
@Import({MvcConfig.class})
public class AnotherConfig {
....
}
Pour votre question 2 -
Ici, spring enregistre non seulement MyConfiguration.class
, mais également toutes les classes de composants présentes dans le package dans lequel MyConfiguration
est défini.
Solution à la question 1:
Oui, vous pouvez utiliser @Componentscan
dans autant de classes de configuration. C'est tout pour vous. Il enregistre simplement les différentes classes annotées de certains paquets spécifiques en tant que beans. Donc si vous avez tout le composant des classes annotées analysé en utilisant simplement un @Componentscan
, c'est assez, car tous les beans requis que vous vouliez ont été activés et enregistrés dans le conteneur DispatcherServlet .
Solution à la question 2:
@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
}
Ta question: Pourquoi ici analyser la classe de configuration elle-même?
Cette @ComponentScan(basePackageClasses = { MyConfiguration.class })
mentionne MyConfiguration.class à titre d'exemple. La question est qu'est-ce que cela signifie?
Il existe deux façons d'analyser les packages components en utilisant l'attribut basepackage
ou basepackageclasses
. Ces deux sont identiques, mais l’utilisation de basepackageclasses
présente deux avantages:
Il est à la fois compatible avec le type de texte et ajoute la prise en charge IDE pour les futurs refactoring.
Cela signifie simplement qu'à l'avenir, vous pourrez renommer (via refactor) certains des backages de base, et puisque vous avez renommé les packages de base, vous n'avez pas besoin de changer @ComponentScan dans vos classes de configuration si vous avez utilisé l'attribut basepackageclasses
. .
Revenons maintenant à votre deuxième question. Pourquoi MyConfiguration.class est-il spécifié avec la valeur de l'attribut basepackageclasses
de @Componentscan
?
Tout d’abord, laissez-nous savoir ceci:basepackageclasses
attribut prend la valeur de chaîne qui représente une classe de marqueur. Cette classe de marqueurs dit: Hey! enregistre toutes les classes présentes dans le package dans lequel cette classe est présente, y compris cette classe
Donc, ici, dans votre réponse, toutes les classes analysées par composant qui sont présentes dans le package dans lequel MyConfiguration.class est présent.
Par conséquent, Myconfiguration.class agit en tant que Configuration classe ainsi que le marqueur classe à composant scanne également d’autres classes. Ce qui implique également que toutes les classes annotées, présentes dans le package dans lequel MyConfiguration.class est présent, seront enregistrées, y compris MyConfiguration.class car elle est annotée avec l'annotation @Configuration
L'attribut basepackageclasses
peut également avoir d'autres classes, comme com.abc.org.Marker.class
Avantage:
Donc, si vous renommez des paquets, il n'y a pas de problème, car vous avez des classes de marqueurs, qui vous aident à trouver les paquets. Ces classes de marqueurs peuvent contenir ou non du contenu, car elles servent simplement de marqueur pour rechercher des packages.
De la documentation:
Q1:
@Configuration est méta-annoté avec @Component. Par conséquent, les classes @Configuration sont candidates à l'analyse de composants (généralement à l'aide de l'élément Spring XML) et peuvent donc également tirer parti de @ Autowired/@ Inject, comme tout @Component standard.
Les classes @Configuration peuvent non seulement être amorcées à l'aide de l'analyse de composant, mais peuvent également configurer elles-mêmes l'analyse de composant à l'aide de @ComponentScan annotation:
@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {
// various @Bean definitions ...
}
Q2:
basePackageClasses
public abstract Class<?>[] basePackageClasses
Alternative type-sécurisée à basePackages () pour spécifier les packages à analyser pour les composants annotés. Le package de chaque classe spécifiée sera analysé .
Répondez à votre question modifiée
À un moment donné, vous devez indiquer au printemps où se trouvent les fèves dont votre application a besoin. Vous pouvez utiliser par exemple:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
ou en utilisant l'ancien style xml:
<context:component-scan base-package="com.acme" />
En utilisant @ComponentScan au niveau @Configuration, vous vous assurez que toutes les dépendances de cette classe de configuration seront disponibles. En utilisant @CompenentScan avec basePackageClasses, vous enregistrez tous les composants disponibles dans le même package que la classe spécifiée.
Si vous avez déjà indiqué à spring quels paquets il doit analyser, à un endroit ou à une autre manière, vous n’avez pas besoin de l’utiliser. Le morceau de code à votre Q2 est juste un exemple de ce que le printemps est capable de faire.