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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25550494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:38:09  来源:igfitidea点击:

ComponentScan excludeFilters Not Working In Spring 4.0.6.RELEASE

javaspringunit-testingdependency-injection

提问by Ripu Daman

I have a class which I want to exclude while component scanning. I am using the below code to do that but that doesn't seem to work although everything seems to be right

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

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

Actually I want have "ServiceImpl" class, which implements "Service" interface, is being used in my rest api logic and while doing the integration test of an api I want to exclude this implmentation and load the mocked implementation. But this doesn't seem to happen as even after using the above I am getting the below error

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

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

I spent too much of time on this but nothing works.

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

Any help is appreciated.

任何帮助表示赞赏。

采纳答案by Ripu Daman

After lot of work and research I noticed that Spring's behavior is little weird in term of component scanning.

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

Artifacts were like this :

文物是这样的:

ServiceImplis the real implementation class which implements Serviceinterface. ServiceMockImplis the mocked implantation class which implements Serviceinterface.

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

I wanted to tweak the component scanning so that it only loads the ServiceMockImplbut not ServiceImpl.

我想调整组件扫描,使其只加载ServiceMockImpl但不加载ServiceImpl.

I had to add the @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class), in the @ComponentScanof test configuration class, to exclude that particular class from component scanning. But both the classes were getting loaded even after doing the above changes and tests were failing.

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

After lot of work and research I found that the ServiceImplwas getting loaded because of the other class which was getting loaded and has @ComponentScanfor all packages on top of in it. So I added the code to exclude the Applicationclass from the component scanning as follows @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Application.class).

经过大量的工作和研究,我发现它ServiceImpl被加载是因为另一个类正在被加载并且@ComponentScan所有包都在它上面。所以我添加了代码以Application从组件扫描中排除该类,如下所示@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Application.class)

After that it worked as expected.

之后它按预期工作。

Code like below

代码如下

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

I have seen that lot of questions on component scanning are unanswered for long hence I thought to add these details as it may help somebody in the future.

我已经看到很多关于组件扫描的问题长期以来都没有答案,因此我想添加这些细节,因为它可能在未来对某人有所帮助。

HTH...

哈...

回答by Forest10

At first,Thanks very much about the answers of @Yuriy and @ripudam,but what makes me confused is when my excludeFilters contains Configuration.class I have to use @Import to import the Classe which annotated by @Configuration.I found when i use excludeFilters = {@Filter(type = FilterType.ANNOTATION,value{EnableWebMvc.class,Controller.class}),all works well.The ContextLoaderListener doesn`t regist the Controller at first.

首先,非常感谢@Yuriy 和@ripudam 的回答,但让我感到困惑的是,当我的 excludeFilters 包含 Configuration.class 时,我必须使用 @Import 来导入由 @Configuration.I 注释的 Classe。我在使用时发现excludeFilters = {@Filter(type = FilterType.ANNOTATION,value{EnableWebMvc.class,Controller.class}),一切正常。ContextLoaderListener 一开始不注册控制器。

For example

例如

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

回答by dorony

I had an issue when using @Configuration, @EnableAutoConfigurationand @ComponentScanwhen trying to exclude specific configuration classes, but it didn't work!

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

Eventually I solved the problem by using @SpringBootApplication, which according to Spring documentation does the same functionality as the three above in one annotation.

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

Another Tip is to try first without refining your package scan (without the basePackages filter).

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

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