web-dev-qa-db-fra.com

ComponentScan excludeFilters ne fonctionne pas au printemps 4.0.6.LELEASE

J'ai une classe que je veux exclure lors de l'analyse de composants. J'utilise le code ci-dessous pour le faire mais cela ne semble pas fonctionner alors que tout semble être correct

@ComponentScan(basePackages = { "common", "adapter", "admin"}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class) })

En fait, je souhaite que la classe "ServiceImpl", qui implémente l'interface "Service", soit utilisée dans ma logique d'API restante et lors du test d'intégration d'une API, je souhaite exclure cette implémentation et charger l'implémentation simulée. Mais cela ne semble pas se produire car même après avoir utilisé ce qui précède, je reçois l'erreur ci-dessous.

No qualifying bean of type [admin.Service] is defined: expected single matching bean but found 2: ServiceMockImpl,ServiceImpl

J'ai passé trop de temps là-dessus mais rien ne fonctionne.

Toute aide est appréciée.

11
Ripu Daman

Après beaucoup de travail et de recherche, j'ai remarqué que le comportement de Spring est peu étrange en termes d'analyse de composants.

Les artefacts étaient comme ça:

"ServiceImpl" est la véritable classe d'implémentation qui implémente l'interface "Service". "ServiceMockImpl" est la classe d'implantation fictive qui implémente l'interface "Service".

Je voulais Tweak l'analyse du composant afin qu'il ne charge que le "ServiceMockImpl" mais pas "ServiceImpl".

J'ai dû ajouter "@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class)" dans le "@ComponentScan" de la classe de configuration de test pour exclure cette classe particulière de l'analyse des composants. Mais les deux classes étaient chargées même après avoir effectué les modifications ci-dessus et les tests échouaient.

Après beaucoup de travail et de recherche, j'ai découvert que "ServiceImpl" était en train d'être chargé à cause de l'autre classe qui était en train de l'être et sur laquelle se trouvait "@ComponentScan" pour tous les paquets. J'ai donc ajouté le code pour exclure la classe "Application" de l'analyse du composant, comme suit "@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, value = Application.class)".

Après cela, cela a fonctionné comme prévu.

Code comme ci-dessous

@ComponentScan(
    excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = OAuthCacheServiceImpl.class),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Application.class)
    },
    basePackages = {
        "common", "adapter", "admin"
    }
)

J'ai vu que beaucoup de questions sur l'analyse des composants restaient sans réponse depuis longtemps, alors j'ai pensé ajouter ces détails, car cela pourrait aider quelqu'un à l'avenir.

HTH ...

30
Ripu Daman

Au début, merci beaucoup pour les réponses de @Yuriy et de @ ripudam, mais ce qui me rend confus, c’est lorsque mon excludeFilters contient Configuration.class. Je dois utiliser @Import pour importer la classe annotée par @ Configuration.J'ai trouvé lors de l'utilisation excludeFilters = {@Filter (type = FilterType.ANNOTATION, valeur {EnableWebMvc.class, Controller.class}), tout fonctionne correctement. Le ContextLoaderListener n'enregistre pas le contrôleur pour la première fois.

Par exemple 

//@Import(value = { SecurityConfig.class, MethodSecurityConfig.class, RedisCacheConfig.class, QuartzConfig.class })
@ComponentScan(basePackages = { "cn.myself" }, excludeFilters = {
        @Filter(type = FilterType.ANNOTATION,value={EnableWebMvc.class,Controller.class}) })
public class RootConfig {
}
1
Forest10

J'ai eu un problème en utilisant @Configuration , @EnableAutoConfiguration et @ComponentScan en essayant d'exclure des classes de configuration spécifiques, le problème est que cela n'a pas fonctionné! 

Finalement, j'ai résolu le problème en utilisant @SpringBootApplication , qui, selon la documentation de Spring, offre les mêmes fonctionnalités que les trois précédentes en une seule annotation.

Une autre astuce consiste à essayer d’abord sans affiner l’analyse de votre paquet (sans le filtre basePackages).

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
0
dorony