web-dev-qa-db-fra.com

@ComponentScan avec plusieurs classes de configuration: Configuration basée sur les annotations

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 @ComponentScandans n'importe quel de la classe @Configurationou 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.

5
user4768611

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 -

  1. Pour enregistrer le bean @Configuration dans rootcontext ou dispatchersevletcontext.
  2. Pour importer ce @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.

7
TheCurious

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:
basepackageclassesattribut 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.

1
Tahir Hussain Mir

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.

0
alfcope