J'ai un composant que je souhaite exclure d'un @ComponentScan
dans un particulier @Configuration
:
@Component("foo") class Foo {
...
}
Sinon, il semble entrer en conflit avec une autre classe de mon projet. Je ne comprends pas entièrement la collision, mais si je commente l' @Component
annotation, les choses fonctionnent comme je le souhaite. Mais d'autres projets qui reposent sur cette bibliothèque s'attendent à ce que cette classe soit gérée par Spring, donc je veux l'ignorer uniquement dans mon projet.
J'ai essayé d'utiliser @ComponentScan.Filter
:
@Configuration
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
mais cela ne semble pas fonctionner. Si j'essaye d'utiliser FilterType.ASSIGNABLE_TYPE
, j'obtiens une erreur étrange concernant l'impossibilité de charger une classe apparemment aléatoire:
Causée par: java.io.FileNotFoundException: la ressource de chemin de classe [junit / framework / TestCase.class] ne peut pas être ouverte car elle n'existe pas
J'ai également essayé d'utiliser type=FilterType.CUSTOM
comme suit:
class ExcludeFooFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
return metadataReader.getClass() == Foo.class;
}
}
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
Mais cela ne semble pas exclure le composant de l'analyse comme je le souhaite.
Comment l'exclure?
la source
L'utilisation de types explicites dans les filtres d'analyse est moche pour moi. Je pense qu'une approche plus élégante consiste à créer sa propre annotation de marqueur:
@Retention(RetentionPolicy.RUNTIME) public @interface IgnoreDuringScan { }
Marquer le composant à exclure avec lui:
@Component("foo") @IgnoreDuringScan class Foo { ... }
Et excluez cette annotation de l'analyse de vos composants:
@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class)) public class MySpringConfiguration {}
la source
@Component
, mais je ne pense pas que ce soit ce que la question poseUne autre approche consiste à utiliser de nouvelles annotations conditionnelles. Depuis plain Spring 4, vous pouvez utiliser l'annotation @Conditionnelle:
@Component("foo") @Conditional(FooCondition.class) class Foo { ... }
et définissez une logique conditionnelle pour l'enregistrement du composant Foo:
public class FooCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // return [your conditional logic] } }
La logique conditionnelle peut être basée sur le contexte, car vous avez accès à la fabrique de bean. Par exemple, lorsque le composant "Bar" n'est pas enregistré comme bean:
return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());
Avec Spring Boot (devrait être utilisé pour CHAQUE nouveau projet Spring), vous pouvez utiliser ces annotations conditionnelles:
@ConditionalOnBean
@ConditionalOnClass
@ConditionalOnExpression
@ConditionalOnJava
@ConditionalOnMissingBean
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication
Vous pouvez éviter la création de classe Condition de cette façon. Reportez-vous à la documentation de Spring Boot pour plus de détails.
la source
Si vous devez définir deux ou plusieurs critères excludeFilters , vous devez utiliser le tableau.
Pour les instances de cette section de code, je souhaite exclure toutes les classes du package org.xxx.yyy et une autre classe spécifique, MyClassToExclude
@ComponentScan( excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })
la source
J'ai eu un problème lors de l'utilisation de @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 ci-dessus dans une annotation.
Une autre astuce consiste à essayer d'abord sans affiner l'analyse de votre package (sans le filtre basePackages).
@SpringBootApplication(exclude= {Foo.class}) public class MySpringConfiguration {}
la source
En cas d'exclusion du composant de test ou de la configuration de test, Spring Boot 1.4 a introduit de nouvelles annotations de test
@TestComponent
et@TestConfiguration
.la source
J'avais besoin d'exclure un audit @Aspect @Component du contexte de l'application, mais uniquement pour quelques classes de test. J'ai fini par utiliser @Profile ("audit") sur la classe d'aspect; en incluant le profil pour les opérations normales mais en l'excluant (ne le mettez pas dans @ActiveProfiles) sur les classes de test spécifiques.
la source