Java 组件扫描排除过滤器在Spring 4.0.6.0版本中不工作

Java 组件扫描排除过滤器在Spring 4.0.6.0版本中不工作,java,spring,unit-testing,dependency-injection,Java,Spring,Unit Testing,Dependency Injection,我有一个我想在扫描组件时排除的类。我正在使用下面的代码来实现这一点,但这似乎不起作用,尽管一切似乎都是正确的 @ComponentScan(basePackages = { "common", "adapter", "admin"}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class) }) 实际上,我想让实现“服务”接口的“ServiceI

我有一个我想在扫描组件时排除的类。我正在使用下面的代码来实现这一点,但这似乎不起作用,尽管一切似乎都是正确的

@ComponentScan(basePackages = { "common", "adapter", "admin"}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class) })
实际上,我想让实现“服务”接口的“ServiceImpl”类在我的rest api逻辑中使用,在对api进行集成测试时,我想排除此实现并加载模拟实现。但这似乎并没有发生,因为即使在使用上面的方法之后,我也会得到下面的错误

No qualifying bean of type [admin.Service] is defined: expected single matching bean but found 2: ServiceMockImpl,ServiceImpl
我在这上面花了太多的时间,但什么都没用


非常感谢您的帮助。

经过大量的工作和研究,我发现Spring的行为在组件扫描方面有点奇怪

工件是这样的:

serviceinpl
是实现
Service
接口的真正实现类。
ServiceMockImpl
是实现
Service
接口的模拟植入类

我想调整组件扫描,使其只加载
servicemockinpl
,而不加载
servicempl

我必须在测试配置类的
@ComponentScan
中添加
@ComponentScan.Filter(type=FilterType.ASSIGNABLE\u type,value=ServiceImpl.class)
,以从组件扫描中排除该特定类。但即使在做了上述更改之后,这两个类仍在加载,并且测试失败


经过大量的工作和研究,我发现
serviceinpl
正在加载,因为另一个类正在加载,并且在它上面有
@ComponentScan
用于所有包。因此,我添加了代码,将
应用程序
类从组件扫描中排除,如下所示
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_type,value=Application.class)

在那之后,它就如预期的那样工作了

代码如下

@ComponentScan(
    excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = OAuthCacheServiceImpl.class),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Application.class)
    },
    basePackages = {
        "common", "adapter", "admin"
    }
)
我已经看到很多关于组件扫描的问题很久没有得到回答,因此我想添加这些细节,因为它可能会在将来帮助别人


HTH…

首先,非常感谢@Yuriy和@ripudam的答案,但让我困惑的是,当我的excludeFilters包含Configuration.class时,我必须使用@Import来导入由@Configuration注释的类。当我使用excludeFilters={@Filter(type=FilterType.ANNOTATION,value)时,我发现{EnableWebMvc.class,Controller.class}),所有这些都可以正常工作。ContextLoaderListener最初并不注册控制器

比如说

//@Import(value = { SecurityConfig.class, MethodSecurityConfig.class, RedisCacheConfig.class, QuartzConfig.class })
@ComponentScan(basePackages = { "cn.myself" }, excludeFilters = {
        @Filter(type = FilterType.ANNOTATION,value={EnableWebMvc.class,Controller.class}) })
public class RootConfig {
}

在尝试排除特定的配置类时,我在使用@Configuration@EnableAutoConfiguration@ComponentScan时遇到问题,但它不起作用

最终,我通过使用解决了这个问题,根据Spring文档,它在一个注释中实现了与上面三个相同的功能

另一个技巧是先尝试,但不优化包扫描(不使用basePackages过滤器)


好主意!这对我来说也是可行的:
@ComponentScan(basePackages=“org.package”,excludeFilters=@Filter(classes={Controller.class,Configuration.class}))
看起来我们必须明确地告诉Spring跳过配置类。Lifesaver…谢谢!
@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}