首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从@ComponentScan中排除@组件

从@ComponentScan中排除@组件
EN

Stack Overflow用户
提问于 2013-09-24 22:03:28
回答 7查看 212.3K关注 0票数 112

我有一个组件,我想在一个特定的@ComponentScan中排除它。

代码语言:javascript
运行
复制
@Component("foo") class Foo {
...
}

否则,它似乎与我的项目中的其他类发生冲突。我并不完全理解冲突,但是如果我注释掉了@Component注释,事情就会像我希望的那样工作。但是其他依赖于这个库的项目期望这个类由Spring来管理,所以我只想在我的项目中跳过它。

我试过用@ComponentScan.Filter

代码语言:javascript
运行
复制
@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:类路径资源junit/framework/TestCase.class由于不存在而无法打开

我还尝试使用type=FilterType.CUSTOM,如下所示:

代码语言:javascript
运行
复制
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.CUSTOM, value=ExcludeFooFilter.class)})
public class MySpringConfiguration {}

但这似乎并没有像我想的那样排除扫描中的成分。

我怎么排除它?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-09-24 22:39:12

配置看起来不错,只是您应该使用excludeFilters而不是excludes

代码语言:javascript
运行
复制
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
票数 134
EN

Stack Overflow用户

发布于 2014-12-07 16:06:24

在扫描过滤器中使用显式类型对我来说很难看。我相信更优雅的方法是创建自己的标记注释:

代码语言:javascript
运行
复制
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreDuringScan {
}

标记应与其一起排除的组件:

代码语言:javascript
运行
复制
@Component("foo") 
@IgnoreDuringScan
class Foo {
    ...
}

并从组件扫描中排除此注释:

代码语言:javascript
运行
复制
@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
票数 59
EN

Stack Overflow用户

发布于 2014-12-06 16:11:04

另一种方法是使用新的条件注释。由于普通的 Spring 4,您可以使用@条件注释:

代码语言:javascript
运行
复制
@Component("foo")
@Conditional(FooCondition.class)
class Foo {
    ...
}

并定义用于注册Foo组件的条件逻辑:

代码语言:javascript
运行
复制
public class FooCondition implements Condition{
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // return [your conditional logic]
    }     
}

条件逻辑可以基于上下文,因为您可以访问bean工厂。例如,当"Bar“组件未注册为bean时:

代码语言:javascript
运行
复制
    return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());

使用Spring的(应该用于每个新的Spring项目),您可以使用以下条件注释:

  • @ConditionalOnBean
  • @ConditionalOnClass
  • @ConditionalOnExpression
  • @ConditionalOnJava
  • @ConditionalOnMissingBean
  • @ConditionalOnMissingClass
  • @ConditionalOnNotWebApplication
  • @ConditionalOnProperty
  • @ConditionalOnResource
  • @ConditionalOnWebApplication

这样可以避免条件类的创建。有关更多细节,请参阅Spring文档。

票数 35
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18992880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档