如何动态配置@ComponentScan?

问题描述 投票:0回答:2
@ComponentScan(  //CS1
    basePackages = {"com.package.A", "com.package.B"},
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
                                           value = {com.Package.A.SomeClass.class
                                           })
)

@ComponentScan(  //CS2
    basePackages = { "com.package.A"}
)
@EnableAutoConfiguration
@SpringBootApplication
public class Application {
  public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
  }
}

上面是我的

SpringBootApplication
的主类。如你所见,我必须使用Annnotation,而不是xml。有两个
@ComponentScan
注解。当然,Spring 不允许这样做。对我来说,两个不同的
@ComponentScan
意味着两种不同的方式来启动我的应用程序。如果我选择使用CS1(这意味着@ComponentScan1),我必须评论CS2,反之亦然。

它不优雅或优美。特别是对于那些 Spring 新手。所以我想知道如何根据我的 .properties 文件动态配置它。例如我的 .properties 文件中名为“isScanA”的参数是的,那么我可以使用CS1。或者任何其他优雅的方式。

我已经尝试了很多。

  1. 使用占位符。如

    @ComponentScan(basePackage="${scan.basePackage}")
    。并在需要时更改.properties文件中的值。但这样并不能解决
    excludeFilters
    。因为如果我使用
    FilterType.ASSIGNABLE_TYPE
    来分配需要排除的类,则
    value
    应该是
    Class
    类型而不是
    String
    ,如果使用
    value = {"${scan.excludeClass}"}
    的话。

  2. 编程方式。

    /**
     * Create a new AnnotationConfigApplicationContext, scanning for bean definitions
     * in the given packages and automatically refreshing the context.
     * @param basePackages the packages to check for annotated classes
     */
    public AnnotationConfigApplicationContext(String... basePackages) {
        this();
        scan(basePackages);
        refresh();
    }
    

我在主函数中调用了这个方法。但是它也无法解决

excludeFilters
问题,原因在这里:以编程方式执行上下文:组件扫描?

...

我真的尝试了很多,但还是无法解决。所以我需要你的帮助。

请原谅我糟糕的英语,请。

非常感谢,至少你花了一点时间阅读。

java spring spring-annotations component-scan
2个回答
5
投票

也许您正在寻找 Spring 的简介! Spring Profile 允许您确定配置和 Bean 的配置文件。我认为你必须将配置类分开才能有两个配置文件!看看这些例子!

这是文档:

http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/boot-features-profiles.html


0
投票

假设您有两个包“com.package.A”和“com.package.B” 并且您希望始终 @ComponentScan package.A 并希望根据某些配置(在 application.properties 中的某处定义)扫描 package.B。

您可以在应用程序的@ComponentScan下添加package.A,对于其他package.B,您可以将@ComponentScan和@ConditionalOnProperty组合在一起来完成它,其中仅当属性“X”的值相等时到一些“Y”然后@ComponentScan将被渲染并且该包将被扫描。

//Normal Application level @ComponentScan
@SpringBootApplication
@ComponentScan(basePackages = { "com.package.A" })

其他包裹可以通过

根据某些属性进行扫描
//@ComponentScan which is dependent on property X
@Service
@ConditionalOnProperty(name = "X", havingValue = "Y")
@ComponentScan(basePackages = { "com.package.B"})
@Primary
public class Service extends ServiceImpl { }

仅当 X 的属性为 Y com.package.B 时才会被扫描,并创建其下的所有 Bean,否则您的应用程序将继续仅扫描 com.package.A

© www.soinside.com 2019 - 2024. All rights reserved.