Spring引导ComponentScan excludeFIlters不排除

时间:2018-01-04 20:12:58

标签: java spring spring-boot spring-test

我正在使用 SimpleTest

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

以及此测试的配置

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

我正在尝试排除 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");
    }
}

应用程序类如下所示:

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);
    }
}

但是出于一个非常奇怪的原因, Starter 类仍在初始化。

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

3 个答案:

答案 0 :(得分:12)

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

解决此问题的一种方法是提供模拟import org.springframework.boot.test.mock.mockito.MockBean; public class SimpleTest { @MockBean private Starter myTestBean; ... } bean:

@PostConstruct

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

其他常见解决方案:

  • 不要在任何单元测试中直接使用@Profile("!TEST")
  • Starter
  • 上使用Spring配置文件和注释,例如@ConditionalOn...
  • Starter
  • 上使用spring Boot return [ { type: AuthActions.SIGNIN }, { type: AuthActions.SET_TOKEN, payload: res['authToken'] } ]; 注释

答案 1 :(得分:0)

@SpringBootApplication,根据Spring文档的组合功能: 用一种表示法 @Configuration @EnableAutoConfiguration @ComponentScan

首先尝试不改进包扫描(不使用basePackages过滤器)。

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

答案 2 :(得分:0)

您可以定义自定义组件扫描过滤器以将其排除。

示例代码如下:

@SpringBootApplication()
@ComponentScan(excludeFilters=@Filter(type = FilterType.REGEX, pattern="com.wyn.applications.starter.Starter*"))
public class SimpleTestConfig {

}

这适合我。

如需进一步阅读,请转到blog