java Spring boot ComponentScan excludeFIlters 不排除
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48102883/
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
Spring boot ComponentScan excludeFIlters not excluding
提问by Daniel Taub
I am having a SimpleTest:
我有一个SimpleTest:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SimpleTestConfig.class)
public class SimpleTest {
@Test
public void test() {
assertThat(true);
}
}
and a configurationfor this test :
以及此测试的配置:
@SpringBootApplication
@ComponentScan(basePackageClasses = {
SimpleTestConfig.class,
Application.class
},
excludeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = Starter.class))
public class SimpleTestConfig {
}
I am trying to exclude the Starterclass
我正在尝试排除Starter类
package application.starters;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Starter {
@PostConstruct
public void init(){
System.out.println("initializing");
}
}
And the Applicationclass looks like this :
和应用类如下所示:
package application;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import static org.springframework.boot.SpringApplication.run;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
run(Application.class, args);
}
}
But for a very weird reason the Starterclass is still getting initialized.
但是出于一个非常奇怪的原因,Starter类仍在初始化。
Can anyone explain why the ComponentScan excludeFilters
is not excluding my Starter
class ?
谁能解释为什么ComponentScan excludeFilters
不排除我的Starter
班级?
回答by tkruse
Each component scan does filtering individually. While you exclude Starter.class
from SimpleTestConfig
, SimpleTestConfig
initializes Application
, which does it's own @ComponentScan
without excluding Starter
.
The clean way of using ComponentScan is for each ComponentScan to scan separate packages, that way each filter works fine. When 2 separate ComponentScans scan the same package (as in your tests), this does not work.
每个组件扫描单独进行过滤。当您排除Starter.class
from 时SimpleTestConfig
,SimpleTestConfig
initializes Application
,它在@ComponentScan
不排除的情况下是自己的Starter
。使用 ComponentScan 的干净方式是让每个 ComponentScan 扫描单独的包,这样每个过滤器都可以正常工作。当 2 个单独的 ComponentScans 扫描同一个包时(如在您的测试中),这不起作用。
One way to trick this is to provide a mock Starter
bean:
解决这个问题的一种方法是提供一个模拟Starter
bean:
import org.springframework.boot.test.mock.mockito.MockBean;
public class SimpleTest {
@MockBean
private Starter myTestBean;
...
}
Spring will use that mock instead of the real class, thus the @PostConstruct
method will not be called.
Spring 将使用该模拟而不是真正的类,因此@PostConstruct
不会调用该方法。
Other common solutions:
其他常见解决方案:
- Do not directly use
Application.class
in any unit test - Use Spring profile and annotations such as
@Profile("!TEST")
on theStarter
class - Use a spring Boot
@ConditionalOn...
annotation on theStarter
class
- 不要
Application.class
在任何单元测试中直接使用 @Profile("!TEST")
在Starter
类上使用 Spring 配置文件和注释@ConditionalOn...
在Starter
类上使用 spring Boot注释
回答by Yogi
You can define custom component scan filter for excluding it.
您可以定义自定义组件扫描过滤器以排除它。
Example code will be like:
示例代码将类似于:
@SpringBootApplication()
@ComponentScan(excludeFilters=@Filter(type = FilterType.REGEX, pattern="com.wyn.applications.starter.Starter*"))
public class SimpleTestConfig {
}
This works for me.
这对我有用。
For further reading go to this blog.
如需进一步阅读,请访问此博客。
回答by dorony
@SpringBootApplication, according to Spring documentation does the combined functionality of: @Configuration, @EnableAutoConfigurationand @ComponentScanin one notation.
@SpringBootApplication,根据 Spring 文档,在一种符号中组合了以下功能: @Configuration、@EnableAutoConfiguration和@ComponentScan。
Try first without refining your package scan (without the basePackages filter).
首先尝试不优化您的包扫描(没有 basePackages 过滤器)。
@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}