【问题标题】:ComponentScan excludeFilters Not Working In Spring 4.0.6.RELEASEComponentScan excludeFilters 在 Spring 4.0.6.RELEASE 中不起作用
【发布时间】:2014-10-22 09:58:47
【问题描述】:

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

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

实际上,我希望在我的其余 api 逻辑中使用实现“Service”接口的“ServiceImpl”类,并且在对 api 进行集成测试时,我想排除这个实现并加载模拟的实现。但这似乎并没有发生,因为即使在使用上述内容后我也收到以下错误

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

我在这方面花了太多时间,但没有任何效果。

感谢任何帮助。

【问题讨论】:

    标签: java spring unit-testing dependency-injection


    【解决方案1】:

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

    神器是这样的:

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

    我想调整组件扫描,使其仅加载 ServiceMockImpl 而不是 ServiceImpl。

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

    经过大量工作和研究,我发现 ServiceImpl 正在加载,因为另一个类正在加载,并且其中所有包都包含 @ComponentScan。所以我添加了代码以从组件扫描中排除Application类,如下@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...

    【讨论】:

    • 好主意!这对我也有用:@ComponentScan(basePackages = "org.package", excludeFilters = @Filter(classes = {Controller.class, Configuration.class}) ) 看起来我们必须明确告诉 Spring 跳过配置类。
    • 救生员...谢谢!
    【解决方案2】:

    我在尝试排除特定配置类时使用 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 时遇到问题,但它没有不行!

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

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

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

    【讨论】:

      【解决方案3】:

      首先,非常感谢@Yuriy 和@ripudam 的回答,但让我感到困惑的是,当我的excludeFilters 包含Configuration.class 时,我必须使用@Import 导入由@Configuration 注释的Classe。我发现当我使用 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 {
      }
      

      【讨论】:

        猜你喜欢
        • 2017-06-10
        • 2018-06-14
        • 1970-01-01
        • 2016-06-02
        • 2016-11-23
        • 1970-01-01
        • 2018-10-17
        • 2014-07-05
        • 1970-01-01
        相关资源
        最近更新 更多