我想要从特定@ComponentScan
的{{1}}中排除某个组件:
@Configuration
否则,它似乎与我项目中的其他类冲突。我并不完全理解碰撞,但如果我注释掉@Component("foo") class Foo {
...
}
注释,那么事情就像我想要的那样。但是依赖这个库的其他项目希望这个类由Spring管理,所以我想只在我的项目中跳过它。
我尝试使用@Component
:
@ComponentScan.Filter
但它似乎不起作用。如果我尝试使用@Configuration
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
,我会因为无法加载一些看似随机的类而得到一个奇怪的错误:
引起:java.io.FileNotFoundException:无法打开类路径资源[junit / framework / TestCase.class],因为它不存在
我还尝试使用FilterType.ASSIGNABLE_TYPE
,如下所示:
type=FilterType.CUSTOM
但这似乎并没有像我想要的那样从扫描中排除组件。
如何排除它?
答案 0 :(得分:77)
配置似乎没问题,除了您应该使用excludeFilters
而不是excludes
:
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
答案 1 :(得分:39)
在扫描过滤器中使用显式类型对我来说很难看。我相信更优雅的方法是创建自己的标记注释:
public @interface IgnoreDuringScan {
}
标记应该用它排除的组件:
@Component("foo")
@IgnoreDuringScan
class Foo {
...
}
并从组件扫描中排除此注释:
@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
答案 2 :(得分:22)
另一种方法是使用新的条件注释。 从 plain 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
您可以通过这种方式避免创建Condition类。有关更多详细信息,请参阅Spring Boot文档。
答案 3 :(得分:9)
如果您需要定义两个或更多 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) })
答案 4 :(得分:7)
在尝试排除特定配置类时,使用 @Configuration , @EnableAutoConfiguration 和 @ComponentScan 时出现问题,问题是它没用!
最终我使用@SpringBootApplication解决了这个问题,根据Spring文档,它在一个注释中执行与上述三个相同的功能。
另一个提示是首先尝试不进行包扫描(不使用basePackages过滤器)。
@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
答案 5 :(得分:1)
如果排除测试组件或测试配置,Spring Boot 1.4引入了新的测试注释@TestComponent
and @TestConfiguration
。
答案 6 :(得分:0)
我需要从应用程序上下文中排除审核@Aspect @Component,但仅适用于一些测试类。我最终在方面类上使用@Profile(“ audit”);包括正常操作的配置文件,但不包括特定测试类的配置文件(不要将其放在@ActiveProfiles中)。