包装上的条件ComponentScan

时间:2016-08-26 13:36:36

标签: spring spring-boot

在Spring Boot应用程序中,我有一个包含Application类的包,如

@SpringBootApplication
class Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application);
        application.run(args);
    }

}

默认情况下会自动从该类的包中设置ComponentScan。然后我有几个子包,每个子包包含几个组件和服务bean(使用注释)。但是为了针对不同的用例重用此应用程序,我需要启用/禁用某些子包中的所有组件,最好是通过属性。

那就是我有像

这样的子包
org.example.app.provider.provider1
org.example.app.provider.provider2

现在,基于某些属性,我想在其中一个软件包中启用(扫描)bean,例如

provider1.enabled=true

我以为我可以让Configuration类上的ConditionalOnProperty像这样工作,但问题是,bean是由默认的@SpringBootApplication组件扫描拾取的(即子包配置类不会覆盖顶级组)

所以我认为我会排除这些软件包,但是当需要一个新的提供程序包时,这会增加更多的工作(和知识)(需要事先知道为该软件包添加一个显式的排除)。

有什么其他方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:7)

有条件地加载提供程序组件

使用@ConditionalOnProperty注释的Spring配置就是这样做的:

@Configuration
@ComponentScan("org.example.app.provider.provider1")
@ConditionalOnProperty(name = "provider1.enabled", havingValue = "true")
public class Provider1Configuration {
}

@Configuration
@ComponentScan("org.example.app.provider.provider2")
@ConditionalOnProperty(name = "provider2.enabled", havingValue = "true")
public class Provider2Configuration {
}

然后排除org.example.app.provider.*

下的组件

现在,您只需要从Spring Boot Application中排除提供程序(并让CondtionalOnProperty完成其工作)。你可以:

  • (1)移动提供程序包,使其不低于 Spring Boot应用程序

例如,如果Spring Boot主要位于org.example.app,请将@Configuration保留在org.example.app中,将提供者保留在org.example.providers

  • (2)或者从Spring Boot中排除提供程序包(假设@Configuration位于org.example.app中):

<强> SpringBootMain.java:

@SpringBootApplication
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "org.example.app.provider.*"))
class Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application);
        application.run(args);
    }
}
相关问题