当前位置: 首页 > 知识库问答 >
问题:

从@ComponentScan中排除@Component

唐利
2023-03-14

我想从特定@Configuration中的@ComponentScan中排除一个组件:

@Component("foo") class Foo {
...
}

否则,它似乎会与我项目中的其他类发生冲突。我并不完全理解这种冲突,但是如果我注释掉< code>@Component注释,事情就会如我所愿地运行。但是其他依赖这个库的项目期望这个类由Spring管理,所以我只想在我的项目中跳过它。

我尝试使用< code>@ComponentScan。过滤器:

@Configuration 
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}

但是它似乎不起作用。如果我尝试使用FilterType.ASSIGNABLE_TYPE,我会收到一个奇怪的错误,因为无法加载一些看似随机的类:

由以下原因引起:java.io.文件未发现异常:类路径资源 [junit/框架/测试用例.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.CUSTOM, value=ExcludeFooFilter.class)})
public class MySpringConfiguration {}

但这似乎并没有像我希望的那样将组件排除在扫描范围之外。

如何排除它?

共有3个答案

关胜
2023-03-14

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

@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文档。

司徒俊良
2023-03-14

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

@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreDuringScan {
}

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

@Component("foo") 
@IgnoreDuringScan
class Foo {
    ...
}

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

@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
汪修诚
2023-03-14

配置似乎没问题,只是您应该使用excludeFilters而不是exclude

@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
 类似资料:
  • 问题内容: 我有一个要从特定对象中排除的组件: 否则,它似乎与我项目中的其他班级发生冲突。我不完全理解碰撞,但是如果注释掉注释,事情就会像我希望的那样工作。但是其他依赖于此库的项目希望此类由Spring管理,因此我只想在我的项目中跳过它。 我尝试使用: 但它似乎不起作用。如果尝试使用,则会收到一个奇怪的错误,提示你无法加载一些看似随机的类: 原因:java.io.FileNotFoundExcep

  • 所以,我已经找了好几个小时了,我完全陷入了困境。 我的问题很简单:我有一个(相当大的)项目,我想用Maven来构建(所以我可以稍微自动化一下)。到目前为止,除了一个主要问题外,一切正常。 我有一个称为“java插件”的依赖项——我不知道它的确切来源或作者,但它在我的依赖项的依赖项中——我将它添加到我们自己的Nexus第三方存储库中,并使用原始jar的名称。 这个插件是从我的Nexus添加的,没有任

  • 问题内容: 当我grep我的Subversion工作副本目录时,结果包括.svn目录中的许多文件。是否可以递归grep目录,但排除.svn目录中的所有结果? 问题答案: 如果您有GNU Grep,它应该像这样工作: 如果碰巧是在没有GNU Grep的Unix系统上,请尝试以下操作:

  • 问题内容: 我已经创建了下面的对象,该对象将被映射到ElasticSearch类型。我想从索引中排除该属性: 问题答案: 您应该能够设置属性的值,如下所示:

  • 我想从类型中排除一个单独的属性。我该怎么做呢? 比如我有 我想排除属性 以获得