35

Let's say I have 5 Spring Boot Projects. All of them have a Maven dependency on a Spring Boot project No 6 with some shared/common classes. 5 independent projects have a lot of common properties assigned at each application.properties, which I'd like to abstract and move them to common project. Overall it looks like this:

                                            Project 1 (app.properties)
Common Project (app-common.properties) <--- Project 2 (app.properties)
                                            Project 3 (app.properties)...

Current problem is that app-common.properties is inside project1.jar/lib/common-project.jar and app-common.properties apparently do not load upon startup.

Is there a way to extend it from a dependency?

CommonProject Main class looks like this:

@SpringBootApplication
public class CommonApplication extends SpringBootServletInitializer {

    protected static void run(SpringApplication application, String[] args) {
        application.run(args);
    }
}

Project1 Main class looks like this:

public class Project1 extends CommonApplication {

    public static void main(String[] args) {
        run(new SpringApplication(Project1.class), args);
    }
}
Mikhail Kholodkov
  • 23,642
  • 17
  • 61
  • 78
  • 1
    Not really. I've ended up extracting all common values/properties to a java class with Constants, where values being @Inject 'ed through setters. And that java class is used in underlying projects. Lame, but quick workaround. If I'll find a better way in the future, I'll post it here. – Mikhail Kholodkov May 24 '17 at 02:28
  • 1
    Thanks, so I actually tried what Anton has below and it worked. I have a common props files in a dependency and using the classpath props it looks to work great. Just put the annotation on where your declared your @SpringBootApplication – codesalsa May 24 '17 at 04:09
  • Thanks for you input! Based on your successful experience, I will accept Anton's answer. – Mikhail Kholodkov Jun 13 '17 at 22:49
  • https://stackoverflow.com/questions/53233781/spring-boot-application-configuration-question do you have input for here? – user3833308 Nov 09 '18 at 22:19
  • How to use profiles in the dependency? – Mohan Nov 27 '21 at 17:27

2 Answers2

33

Use PropertySource annotation and provide two sources for your app:

@PropertySources({
        @PropertySource("classpath:app-common.properties"),
        @PropertySource("classpath:app.properties")
    })

more details can be found there https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Anton
  • 346
  • 4
  • 2
7

Currently spring boot doesn't provide inheriting properties.

A spring boot application supports multiple property sources but the convention (read: built-in logic) for xxx.properties is to resolve the last xxx.properties if there are multiple properties files having the same file name.

There are many solution to this.

One possible solution is to

  1. apply a custom profile to the dependency
  2. include inheritable settings in the application-customprofile.properties
  3. have the dependent(s) set spring.profiles.include=customprofile in application[-{profile}].properties (note: if set in application.properties, it applies for all profiles)

Another possible solution is to use a unique custom filename for the properties.

  • i.e. instead of using the default application.properties, use common.properties
aliopi
  • 3,682
  • 2
  • 29
  • 24
Mathew
  • 71
  • 1
  • 1
  • for example `java -jar myproject.jar --spring.config.name=myproject` https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files – aliopi Feb 05 '18 at 15:16