Comment scanner plusieurs chemins à l'aide de l'annotation @ComponentScan?


89

J'utilise Spring 3.1 et j'amorce une application à l'aide des attributs @Configurationet @ComponentScan.

Le démarrage réel se fait avec

new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);

Cette classe de configuration est annotée avec

@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass

et cela fonctionne très bien. Cependant, j'aimerais être plus précis sur les paquets que je scanne alors j'ai essayé.

@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass

Cependant, cela échoue avec des erreurs me disant qu'il ne peut pas trouver les composants spécifiés à l'aide de l' @Componentannotation.

Quelle est la bonne façon de faire ce que je recherche?

Merci


Deux bonnes réponses données à peu près en même temps pour autant que je sache. Je vais accepter de hage juste parce qu'il a moins de points, mais merci à tous les deux.
Programmation Guy

Si vous vous demandez la même chose pour la version kotlin , vérifiez celui-ci stackoverflow.com/a/62818187/7747942
Sylhare

Réponses:


159

@ComponentScan utilise un tableau de chaînes, comme ceci:

@ComponentScan({"com.my.package.first","com.my.package.second"})

Lorsque vous fournissez plusieurs noms de package dans une seule chaîne, Spring l'interprète comme un seul nom de package et ne peut donc pas le trouver.


48

Il existe une autre alternative de type sécurisé à la spécification d'un emplacement de package de base sous forme de chaîne. Voir l'API ici , mais j'ai également illustré ci-dessous:

@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})

L'utilisation du spécificateur basePackageClasses avec vos références de classe indiquera à Spring d'analyser ces packages (tout comme les alternatives mentionnées ), mais cette méthode est à la fois sûre de type et ajoute le support IDE pour la refactorisation future - un énorme plus dans mon livre.

En lisant l'API, Spring suggère de créer une classe ou une interface de marqueur sans opération dans chaque package que vous souhaitez analyser et qui ne sert à rien d'autre que d'être utilisée comme référence pour / par cet attribut.

OMI, je n'aime pas les classes de marqueurs (mais encore une fois, elles ressemblent à peu près aux classes d'informations sur les packages) mais la sécurité de type, le support IDE et la réduction drastique du nombre de packages de base nécessaires à inclure pour cette analyse est, sans aucun doute, une bien meilleure option.


Quelqu'un pourrait-il expliquer pourquoi @ComponentScan ({"com.app", "com.controllers"}) ne fonctionne pas pour moi mais @ComponentScan (basePackageClasses = {"com.controllers"}) fonctionne bien? Je trouve ça ennuyeux d'écrire chaque nom de classe
xaverras

3
Vous n'avez qu'à spécifier une classe dans le package, pour le package que vous souhaitez analyser. Ceci est connu comme une classe de marqueurs. Si vous avez besoin d'analyser un package plus haut dans la hiérarchie qui n'a pas de classes, spring suggère une technique utilisant une interface "spring marker" ou une classe finale définie dans ce package uniquement dans le but de scanner les packages.
Prancer

17

Indiquez le nom de votre package séparément, il nécessite un String[]pour les noms de package.

Au lieu de cela:

@ComponentScan("com.my.package.first,com.my.package.second")

Utilisez ceci:

@ComponentScan({"com.my.package.first","com.my.package.second"})

10

Une autre façon de faire est d'utiliser le basePackageschamp; qui est un champ dans l'annotation ComponentScan.

@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})

Si vous regardez dans l'annotation ComponentScan .class à partir du fichier jar, vous verrez un champ basePackages qui prend dans un tableau de chaînes

public @interface ComponentScan {
String[] basePackages() default {};
}

Ou vous pouvez mentionner les classes explicitement. Qui prend dans un tableau de classes

Class<?>[]  basePackageClasses

4

Vous utilisez ComponentScan pour analyser plusieurs packages en utilisant

@ComponentScan({"com.my.package.first","com.my.package.second"})


1

assurez-vous d'avoir ajouté cette dépendance dans votre pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Merci après avoir passé près d'une demi-heure, c'était la dépendance manquante
DvixExtract

1

J'utilise:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})

0

Vous pouvez également utiliser l'annotation @ComponentScans:

@ComponentScans(value = { @ComponentScan("com.my.package.first"),
                          @ComponentScan("com.my.package.second") })

4
S'il vous plaît envisager d'ajouter une explication à votre réponse
yeya
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.