yka*_*ich 76 java spring dependency-injection spring-ioc spring-boot
我有一个组件,我想从@ComponentScan
特定的一个组件中排除@Configuration
:
@Component("foo") class Foo {
...
}
Run Code Online (Sandbox Code Playgroud)
否则,它似乎与我项目中的其他类冲突.我不完全理解碰撞,但是如果我注释掉@Component
注释,事情就像我想要的那样.但是依赖这个库的其他项目希望这个类由Spring管理,所以我想在我的项目中跳过它.
我试过用@ComponentScan.Filter
:
@Configuration
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
Run Code Online (Sandbox Code Playgroud)
但它似乎不起作用.如果我尝试使用FilterType.ASSIGNABLE_TYPE
,我得到一个奇怪的错误,无法加载一些看似随机的类:
引起:java.io.FileNotFoundException:类路径资源[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 {}
Run Code Online (Sandbox Code Playgroud)
但这似乎并没有像我想要的那样从扫描中排除组件.
我如何排除它?
Ser*_*mar 87
配置似乎没问题,除了你应该使用excludeFilters
而不是excludes
:
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
Run Code Online (Sandbox Code Playgroud)
lub*_*nac 46
在扫描过滤器中使用显式类型对我来说很难看.我相信更优雅的方法是创建自己的标记注释:
public @interface IgnoreDuringScan {
}
Run Code Online (Sandbox Code Playgroud)
标记应该用它排除的组件:
@Component("foo")
@IgnoreDuringScan
class Foo {
...
}
Run Code Online (Sandbox Code Playgroud)
并从组件扫描中排除此注释:
@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
Run Code Online (Sandbox Code Playgroud)
lub*_*nac 23
另一种方法是使用新的条件注释.从普通的 Spring 4开始,您可以使用@Conditional注释:
@Component("foo")
@Conditional(FooCondition.class)
class Foo {
...
}
Run Code Online (Sandbox Code Playgroud)
并定义用于注册Foo组件的条件逻辑:
public class FooCondition implements Condition{
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// return [your conditional logic]
}
}
Run Code Online (Sandbox Code Playgroud)
条件逻辑可以基于上下文,因为您可以访问bean工厂.例如,当"Bar"组件未注册为bean时:
return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());
Run Code Online (Sandbox Code Playgroud)
使用Spring Boot(应该用于每个新的Spring项目),您可以使用这些条件注释:
@ConditionalOnBean
@ConditionalOnClass
@ConditionalOnExpression
@ConditionalOnJava
@ConditionalOnMissingBean
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication
您可以通过这种方式避免创建Condition类.有关更多详细信息,请参阅Spring Boot文档.
Enr*_*rin 11
如果您需要定义两个或更多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) })
Run Code Online (Sandbox Code Playgroud)
我使用的时候有一个问题@Configuration,@EnableAutoConfiguration和@ComponentScan试图排除特定的配置类的事情是它没有工作!
最终,我通过使用@SpringBootApplication解决了该问题,根据Spring文档,它在一个批注中具有与上述三个功能相同的功能。
另一个提示是先尝试而不完善您的程序包扫描(不使用basePackages筛选器)。
@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
116630 次 |
最近记录: |