membersound
membersound

Reputation: 86667

How to inherit application.properties in Spring?

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

Answers (3)

Silk0vsky
Silk0vsky

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

membersound
membersound

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

Mickael
Mickael

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

Related Questions