从@ComponentScan中排除@Component
我有一个组件,我想从一个特定的@Configuration @ComponentScan中排除: 
 @Component("foo") class Foo { ... } 
 否则,它似乎与我的项目中的其他类冲突。 我不完全理解碰撞,但是如果我注释掉@Component注解,事情就像我想要的那样工作。 但是依赖这个库的其他项目希望这个类由Spring来pipe理,所以我只想在我的项目中跳过它。 
 我试过使用@ComponentScan.Filter : 
 @Configuration @EnableSpringConfigured @ComponentScan(basePackages = {"com.example"}, excludeFilters={ @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)}) public class MySpringConfiguration {} 
 但它似乎没有工作。 如果我尝试使用FilterType.ASSIGNABLE_TYPE ,我得到一个奇怪的错误,无法加载一些看似随机的类: 
引起:java.io.FileNotFoundException:类path资源[junit / framework / TestCase.class]无法打开,因为它不存在
 我也尝试使用type=FilterType.CUSTOM ,如下所示: 
 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 {} 
但是,这似乎并不像我想要的那样从扫描中排除组件。
我如何排除它?
 configuration看起来没问题,除了你应该使用excludeFilters而不是excludes : 
 @Configuration @EnableSpringConfigured @ComponentScan(basePackages = {"com.example"}, excludeFilters={ @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)}) public class MySpringConfiguration {} 
在扫描filter中使用显式types对我来说是丑陋的。 我相信更优雅的方法是创build自己的标记注释:
 public @interface IgnoreDuringScan { } 
标记应该被排除的组件:
 @Component("foo") @IgnoreDuringScan class Foo { ... } 
并从组件扫描中排除此注释:
 @ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class)) public class MySpringConfiguration {} 
另一种方法是使用新的条件注释。 由于普通的 Spring 4你可以使用@Conditional注释:
 @Component("foo") @Conditional(FooCondition.class) class Foo { ... } 
并定义注册Foo组件的条件逻辑:
 public class FooCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // return [your conditional logic] } } 
条件逻辑可以基于上下文,因为你可以访问bean工厂。 例如,当“Bar”组件未注册为bean时:
  return !context.getBeanFactory().containsBean(Bar.class.getSimpleName()); 
使用Spring Boot(应该用于每个新的Spring项目),您可以使用这些条件注释:
-  @ConditionalOnBean
-  @ConditionalOnClass
-  @ConditionalOnExpression
-  @ConditionalOnJava
-  @ConditionalOnMissingBean
-  @ConditionalOnMissingClass
-  @ConditionalOnNotWebApplication
-  @ConditionalOnProperty
-  @ConditionalOnResource
-  @ConditionalOnWebApplication
您可以通过这种方式避免创buildCondition类。 有关更多详细信息,请参阅Spring Boot文档。
如果您需要定义两个或更多的excludeFilters标准,则必须使用该数组。
对于这部分代码中的实例,我想排除org.xxx.yyy包中的所有类和另一个特定的类MyClassToExclude
  @ComponentScan( excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) }) 
 在排除testing组件或testingconfiguration的情况下,Spring Boot 1.4引入了新的testing注释@TestComponent和@TestConfiguration 。 
我在使用@ Configuration , @ EnableAutoConfiguration和@ComponentScan的时候遇到了一个问题,试图排除特定的configuration类,事情是不行的!
最后我通过使用@SpringBootApplication解决了这个问题,根据Spring文档,在一个注释中做了与上面三个相同的function。
另一个提示是首先尝试,而不改善你的包扫描(没有basePackagesfilter)。
 @SpringBootApplication(exclude= {Foo.class}) public class MySpringConfiguration {}