When should I use TypeExcludeFilters in Spring?

纵饮孤独 提交于 2021-02-19 03:36:30

问题


Recently, Spring Boot added TypeExcludeFilters. One prominent use case is the SpringBootApplication annotation.

Before Spring Boot 1.4:

// ...
@ComponentScan
public @interface SpringBootApplication {
// ...

Since Spring Boot 1.4:

// ...
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, 
   classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
// ...

The main motivation seems to improve testing support in Spring, but I fail to get an intuitive understanding of what it does and in what situations it can be beneficial.

Can someone illustrate in a simple example how this new concept is intended to be used?


Background: The change came in Spring 1.4.0 with commit 513dec718fd3e7449ec76b6a916f4696d1942d5d:

Add a new TypeFilter specifically for excluding candidate components. The filter is applied to @SpringBootApplication and allows tests to dynamically contribute exclude filters so that specific classes of component can be excluded.

See gh-5295
See gh-4901


回答1:


One interesting example is @WebMvcTest, because it works thanks to a TypeExcludeFilter:

//...
@TypeExcludeFilters(WebMvcTypeExcludeFilter.class)
//...
public @interface WebMvcTest {
    ...
}

WebMvcTypeExcludeFilter ultimately implements TypeExcludeFilter, which is used to determine if a component/class should not be loaded for this test. Which ones are not included (are excluded)? Well WebMvcTypeExcludeFilter includes some types by default:

static {
    Set<Class<?>> includes = new LinkedHashSet<>();
    includes.add(ControllerAdvice.class);
    includes.add(JsonComponent.class);
    includes.add(WebMvcConfigurer.class);
    ...
    DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
}

In essence, this WebMvcTypeExcludeFilter will match any class that is not "included". By matching the filter, the class will be excluded when loading the spring configuration, effectively applying "only configuration relevant to MVC tests" as stated by the JavaDoc.




回答2:


Say for some reason (e.g. in integration tests) you don't want some beans (even marked with @Component or @Service) to be registered in application context.

This can be achieved by implementing TypeExcludeFilter and applying it to test class:

@SpringBootTest
@TypeExcludeFilters(YourTypeExcludeFilter.class)
public class YouIntegrationTest() {

For an example of how to implement TypeExcludeFilter look at the TestTypeExcludeFilter.



来源:https://stackoverflow.com/questions/41287276/when-should-i-use-typeexcludefilters-in-spring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!