Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!!

like image 298
Ankur Garg Avatar asked Mar 28 '19 17:03

Ankur Garg


People also ask

How do I exclude auto config classes in spring boot?

If you find that specific auto-configure classes are being applied that you don't want, you can use the exclude attribute of @EnableAutoConfiguration to disable them. If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead.

Do we need @configuration in spring boot?

@Configuration is: not required, if you already pass the annotated class in the sources parameter when calling the SpringApplication. run() method; required, when you don't pass the annotated class explicitly, but it's in the package that's specified in the @ComponentScan annotation of your main configuration class.

What is @configuration in spring boot?

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

What is exclude in spring boot?

If you find that specific auto-configuration classes that you do not want are being applied, you can use the exclude attribute of @EnableAutoConfiguration to disable them, as shown in the following example: import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.jdbc.*; import org ...


2 Answers

You can try this it works for me:

@SpringBootApplication
@ComponentScan(excludeFilters  = {@ComponentScan.Filter(
              type = FilterType.ASSIGNABLE_TYPE, classes = {WorkerConfig.class, WorkerExecutors.class, Worker.class})})
like image 95
preetham Avatar answered Oct 15 '22 12:10

preetham


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.

like image 40
Perimosh Avatar answered Oct 15 '22 13:10

Perimosh