Reputation: 2853
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!!
Upvotes: 33
Views: 126761
Reputation: 58
Same situation as the following doesn't work for me either:
@SpringBootApplication
@ComponentScan(basePackages = { "com.myapp" }, excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = { MyClass2.class }) })
I managed to fix it in a not-so-proper manner by putting @ConditionalOn...
on the configuration of module 3 itself and defining the condition through modules 1 and 2. (I did it with a Bean defined in module 1)
@ConditionalOnMissingBean(Module1ClassExample.class)
public class WorkerConfig {
The downside is that module 3 has to be aware of other potential modules, thus, increasing the coupling...
Upvotes: 1
Reputation: 2794
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.
Upvotes: 8
Reputation: 828
You can try this it works for me:
@SpringBootApplication
@ComponentScan(excludeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE, classes = {WorkerConfig.class, WorkerExecutors.class, Worker.class})})
Upvotes: 30