javaspringspring-annotationscomponent-scan

How to config @ComponentScan dynamic?


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

Above is my SpringBootApplication's main class.As you can see,I have to use Annnotation ,not xml. There are two @ComponentScan Annotations.And it is not permitted for Spring, of course. For me, the two different @ComponentScan means two different way to start up my application. And if I choose to use CS1(it means @ComponentScan1), I hava to comment CS2,and vice versa.

It's not elegant or graceful.Especially for those who are newbie for Spring.So I wonder know how can I config it dynamic according to my .properties file.Such as a param in my .properties file called "isScanA" is ture, then I can use CS1. Or any other elegant way.

I have tried a lot.

  1. Use placeholder. Such as @ComponentScan(basePackage="${scan.basePackage}") .And change the value in .properties file when needed. But this way can't fix the excludeFilters. Because if I use FilterType.ASSIGNABLE_TYPE to assign the class which need to be exclude, the value should be a Class type not a String,where if value = {"${scan.excludeClass}"} be used.

  2. Programmatic way.

    /**
     * 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();
    }
    

I called this method in my main function.But it also can't fix the excludeFilters problem, the reason is here:Doing context:component-scan programatic way?

...

I really tried a lot , but still can't fix. So I need your help.

Forgive my poor English, plz.

Thanx a lot, at least you have take a little time to read.


Solution

  • Maybe you are look for Spring's Profile! Spring Profile allow you to determine profiles for Configurations and Beans. I think you must separate the configuration classes to have two profiles! Take a look at those examples!

    Here is the documentation:

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