Reputation: 86667
If I create a commons library having an application.properties
defining common configurations. Like:
spring.main.banner-mode=off
How can I inherit these properties into another project where I include those commons library?
Maven:
<project ...>
<groupId>de.mydomain</groupId>
<artifactId>my-core</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<!-- this one holds the common application.properties -->
<groupId>my.domain</groupId>
<artifactId>my-commons</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
How can I inherit the configuration from my-commons
to my-core
?
Upvotes: 26
Views: 23795
Reputation: 1032
I had a same motivation - to extract common configuration for typical service into a separate starter/library. I've decided to move with EnvironmentPostProcessor
My commons-web
library has its own application-web.properties
with, lets say, single property:
spring.main.banner-mode: off
And EnvironmentPostProcessor
to pick it up
public class DefaultPropertiesEnvironmentPostProcessor implements EnvironmentPostProcessor {
@SneakyThrows
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
environment.getPropertySources()
.addLast(new ResourcePropertySource("application-web.properties"));
}
}
To make it works you need to specify a post processor (on a library side) in resources/META-INF/spring.factories
this way:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.surprise.starter.web.properties.DefaultPropertiesEnvironmentPostProcessor
With such solution it's possible to pick up this config on service side and override it in regular application.properties
I'm not using @PropertySource
cause there is nuance with properties ordering & detection:
...
@PropertySource annotations on your @Configuration classes. Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.
Upvotes: 3
Reputation: 86667
Solution is to include the shared properties using a different name, here application-shared.properties
In shared library:
@SpringBootApplication
@PropertySource(ResourceUtils.CLASSPATH_URL_PREFIX + "application-shared.properties") //can be overridden by application.properties
public class SharedAutoConfiguration {
}
In main app:
@SpringBootApplication
@Import(SharedAutoConfiguration.class)
public class MainAppConfiguration extends SpringBootServletInitializer {
}
This way the commons/shared config gets loaded, but is though able to be overridden in application.properties of main app.
It does not work with the spring.main.banner-mode
property (don't know why), but with all other properties it worked well.
Upvotes: 20
Reputation: 4558
You can try this with Spring.
You can define your src/main/resources/application.properties
in a common module as you mentionned. It will be present in classpath for other project that depends on it.
Then with Annotation @PropertySource
, in other projects that depends on common module :
@Configuration
@PropertySource("classpath*:META-INF/spring/properties/*.properties")
public class Config {
...
}
Or with XML configuration :
<context:property-placeholder location="classpath*:META-INF/spring/properties/*.properties"/>
It should import all the configuration files in the give classpath directory.
Also, you should be aware that you can't have two same files in classpath. You will have a conflict.
For instance, this situation will generate a conflict :
Project A (depends on Project B) :
src/main/resources/application.properties
Project B :
src/main/resources/application.properties
You will have to rename application.properties
file or to put it in a different directory.
Upvotes: 0