ComponentScan excludeFilters在Spring 4.0.6.RELEASE中不起作用

时间:2014-08-28 13:49:16

标签: java spring unit-testing dependency-injection

我有一个类,我想在组件扫描时排除。我使用下面的代码来做到这一点,但似乎没有工作,虽然一切似乎都是正确的

@ComponentScan(basePackages = { "common", "adapter", "admin"}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class) })

实际上我想拥有“ServiceImpl”类,它实现了“Service”接口,正在我的其余api逻辑中使用,在进行api的集成测试时我想要排除这个实现并加载模拟的实现。但这似乎并没有发生,因为即使使用上面的我得到以下错误

No qualifying bean of type [admin.Service] is defined: expected single matching bean but found 2: ServiceMockImpl,ServiceImpl

我花了太多时间在这上面,但没有任何作用。

感谢任何帮助。

3 个答案:

答案 0 :(得分:32)

经过大量的工作和研究后,我注意到Spring在组件扫描方面的行为并不奇怪。

神器是这样的:

" ServiceImpl"是真正的实现类,它实现了" Service"接口。 " ServiceMockImpl"是嘲弄的植入类,它实现了" Service"接口

我想调整组件扫描,以便它只加载" ServiceMockImpl"但不是" ServiceImpl"。

我必须在" @ ComponentScan"中添加" @ ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = ServiceImpl.class)"测试配置类,从组件扫描中排除该特定类。但是即使在完成上述更改并且测试失败之后,这两个类都被加载了。

经过大量的工作和研究,我发现了" ServiceImpl"因为正在加载的其他类而且正在加载并且已经加载了#34; @ 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

答案 1 :(得分:1)

首先,非常感谢@Yuriy和@ ripudam的答案,但令我困惑的是当我的excludeFilters包含Configuration.class时我必须使用@Import导入由@Confit.I发现的Classe。当我使用excludeFilters = {@Filter(type = FilterType.ANNOTATION,value {EnableWebMvc.class,Controller.class})时,一切正常.ContextLoaderListener最初不会注册Controller。

例如

//@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 {
}

答案 2 :(得分:0)

在尝试排除特定配置类时,使用 @Configuration @EnableAutoConfiguration @ComponentScan 时出现问题,问题是它没工作!

最终我使用@SpringBootApplication解决了这个问题,根据Spring文档,它在一个注释中执行与上述三个相同的功能。

另一个提示是首先尝试不进行包扫描(不使用basePackages过滤器)。

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}