简体   繁体   中英

Exclude @Configuration from Spring Boot Application

I have bunch of modules (say 3). Two are Spring boot based module and another one is Spring based. Say Module 1 - SpringBoot Module 2 - Spring Boot Module 3 - Common Module only Spring based

Module 3 @Configuration file defined which needs to be picked only by Module 2 and not 1.

I tried bunch of things to exclude the configuration file. For ex:-

@SpringBootApplication
@ComponentScan(basePackages = {"com.adobe"}
, excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {WorkerConfig.class, WorkerExecutors.class, Worker.class})})
public class Application {

  private static final Logger logger = LoggerFactory.getLogger(Application.class);

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }

}

But Still the @Configiration Class is not getting excluded and Spring is trying to load it in application context which I dont want. My config class

@Configuration
public class WorkerConfig {

  @Bean
  public WorkerExecutors workerExec() {
    WorkerExecutors executors = new WorkerExecutors();
    return executors;
  }

}

Also I do read in @ComponentScan annotation that

 * <p>Note that the {@code <context:component-scan>} element has an
 * {@code annotation-config} attribute; however, this annotation does not. This is because
 * in almost all cases when using {@code @ComponentScan}, default annotation config
 * processing (e.g. processing {@code @Autowired} and friends) is assumed. Furthermore,
 * when using {@link AnnotationConfigApplicationContext}, annotation config processors are
 * always registered, meaning that any attempt to disable them at the
 * {@code @ComponentScan} level would be ignored.

So looks like excluding in Component Scan wont work. Other than above, I also tried excluding using

@SpringBootApplication(exclude= {WorkerExecutors.class, Worker.class,WorkerConfig.class})
public class Application {

But spring boot throws

java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:
    - com.adobe.repository.worker.lib.config.WorkerConfig
    - com.adobe.acp.repository.worker.lib.core.WorkerExecutors
    - com.adobe.acp.repository.worker.lib.core.Worker

Any idea how can I disable component scanning a non spring boot module in a spring boot module other than putting in a different package. I dont want to put in different package.

Any help is appreciated!!

You can try this it works for me:

@SpringBootApplication
@ComponentScan(excludeFilters  = {@ComponentScan.Filter(
              type = FilterType.ASSIGNABLE_TYPE, classes = {WorkerConfig.class, WorkerExecutors.class, Worker.class})})

Auto-config packages lives under org.springframework.boot.autoconfigure. That's the reason why you can't do:

@SpringBootApplication(exclude= {WorkerExecutors.class, Worker.class,WorkerConfig.class})

Spring does what you tell to do. You are calling:

@ComponentScan(basePackages = {"com.adobe"}
, excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {WorkerConfig.class, WorkerExecutors.class, Worker.class})})

Therefore Spring won't load any of those Worker classes. That's why Spring doesn't "execute" your classes annotated with @Configuration.

That said, what you are trying to do doesn't make sense to me. Sounds like you have "modules" (java classes), but all of them are part of the same spring context. If you have a single Spring Context, then you can tell Spring to load some @Configuration classes and not some others. Then, from your "modules", you can inject whatever you need. Module 1 will inject Beans from Module 3, but Module 2 won't. Simple as that.

If for some reason you really need to prevent Module 2 accessing to beans from Module 3, but still keep Module 3 visible from Module 1, then I would separate Module 1 and Module 2 in two different Spring Boot Apps, and Module 3 becomes common code. But this approach may break your current architecture.

UPDATE ON Fri Mar 29 2019

Try this:

@SpringBootApplication
@ComponentScan(basePackages = { "com.myapp" }, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = { MyClass2.class }) })

It worked for me. I have MyClass and MyClass2, and MyClass is loaded and MyClass2 is not. I tried it with Spring Boot 1.5.9.RELEASE and Spring Bom for all the dependencies.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM