Spring引导ComponentScan excludeFIlters不排除

Dan*_*aub 11 java spring spring-test spring-boot

我有一个SimpleTest:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SimpleTestConfig.class)
public class SimpleTest {
    @Test
    public void test() {
        assertThat(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

以及此测试的配置:

@SpringBootApplication
@ComponentScan(basePackageClasses = {
        SimpleTestConfig.class,
        Application.class
},
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ASSIGNABLE_TYPE,
                classes = Starter.class))
public class SimpleTestConfig {
}
Run Code Online (Sandbox Code Playgroud)

我试图排除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");
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序类看起来是这样的:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是由于一个非常奇怪的原因,Starter类仍然被初始化.

任何人都可以解释为什么ComponentScan excludeFilters不排除我的Starter课程?

tkr*_*use 18

每个组件扫描都会单独进行过滤 当你排除Starter.classSimpleTestConfig,SimpleTestConfig初始化Application,这确实是自己的@ComponentScan,但不排除Starter.使用ComponentScan的简洁方法是每个ComponentScan扫描单独的包,这样每个过滤器都可以正常工作.当2个单独的ComponentScans扫描同一个包时(如在测试中),这不起作用.

解决这个问题的一种方法是提供一个模拟Starterbean:

import org.springframework.boot.test.mock.mockito.MockBean;

public class SimpleTest {
    @MockBean
    private Starter myTestBean;
    ...
}
Run Code Online (Sandbox Code Playgroud)

Spring将使用该mock而不是真正的类,因此@PostConstruct不会调用该方法.

其他常见解决方案

  • 不要直接用于Application.class任何单元测试
  • 使用Spring配置文件和注释,例如@Profile("!TEST")Starter类上
  • @ConditionalOn...Starter类上使用spring Boot 注释