I'm working on a data access library and would like to be able to include it as a dependency in other projects with minimal configuration (ideally just autowire a repo). In particular, this library sets itself up using an autoconfiguration class (enabled in spring.factories
) and needs to disable other autoconfiguration classes to work (DataSourceAutoConfiguration
and HibernateJpaAutoConfiguration
).
Is it possible to do this outside of the dependent project?
To make configuration as simple as possible I'd like to avoid putting excludes in the dependent project's @SpringBootApplication
annotation or its spring.autoconfigure.exclude
property.
Update:
On my @Configuration I have tried adding the annotations:
@EnableAutoConfiguration(exclude={
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
this causes
IllegalStateException: Configuration problem: A circular @Import has been detected
and
@ImportAutoConfiguration(exclude={
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
Which simply does nothing.
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.
Disable Auto-configuration Classes. We can also disable the specific auto-configuration classes, if we do not want to be applied. We use the exclude attribute of the annotation @EnableAutoConfiguration to disable the auto-configuration classes.
As per the code snippet, we have used the @EnableAutoConfiguration annotation with the exclude attribute. The DataSourceAutoConfiguration class will be excluded from the auto-configuration.
In Spring Boot 2, if we want our own security configuration, we can simply add a custom WebSecurityConfigurerAdapter. This will disable the default auto-configuration and enable our custom security configuration. Spring Boot 2 also uses most of Spring Security's defaults.
There's a very handy interface called AutoConfigurationImportFilter
, which decides on which auto-configuration should be loaded. This is also how @ConditionalOnClass
annotation works.
In your library, add the following class:
public class MyExclusionFilter
implements AutoConfigurationImportFilter {
private static final Set<String> SHOULD_SKIP = new HashSet<>(
Arrays.asList("org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration",
"org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration"));
@Override
public boolean[] match(String[] classNames, AutoConfigurationMetadata metadata) {
boolean[] matches = new boolean[classNames.length];
for(int i = 0; i< classNames.length; i++) {
matches[i] = !SHOULD_SKIP.contains(classNames[i]);
}
return matches;
}
}
This class needs to be registered in spring.factories
to work. Add the following line in the library into META-INF/spring.factories
:
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=com.mycompany.db.MyExclusionFilter
You don't need to make any changes to the dependent project. Just add the library as a dependency and the auto-configuration you specified won't be loaded for the whole application.
NOTE: You can add more than one import filter, only the auto-configuration classes not filtered in all import filters will get loaded.
For details, see the source code of org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#filter
and org.springframework.boot.autoconfigure.condition.OnClassCondition.java
classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With