2

I am working on a new project and using Spring-Boot for the first time.

Traditionally, when using Spring and property files for configuration, I provided default properties in the distribution (WAR) and allowed for overriding them in some documented place.

For example:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:app.properties</value>
            <value>file:${user.home}/.company/app/app.properties</value>
        </list>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="ignoreResourceNotFound" value="true" />
</bean>

This would allow us to re-deploy the application without losing local system configurations.

After reading the documentation on this for Spring-Boot, it seems that anything in "application.properties" takes a higher priority, and overwrites, anything specified with the @PropertySource annotation.

I like Spring because it allows us to stick to convention, which concerns me that I may have been doing the properties cascading wrong.

What would be the most appropriate way to provide externalized properties, with sensible defaults (embedded database, simple authentication, etc) that are included in the distribution?

Also, if anyone knows, I would love to know the reasoning behind the order for properties in Spring-Boot.

Note

I've tried looking at SpringApplication.setDefaultProperties, but cannot seem to find where to get a reference to the SpringApplication Object. The main method calls a static method on it (run), which is never actually run when bundled as a WAR file. It also seems a little bit of a hack to do it this way.

Justin Smith
  • 413
  • 6
  • 12
  • Where did you normally plan on overriding? Environment variables and JVM properties override `application.properties`. – chrylis -cautiouslyoptimistic- Apr 10 '15 at 01:50
  • I used to use a file under file:${user.home} (in some application specific directory), the problem with JVM and Env variables is that they stick with the application container, so they may affect another app as well – Justin Smith Apr 10 '15 at 02:06
  • 1
    Ah. I do that as well but for those just don't put anything in the jar. I also don't run Spring Boot applications inside an external container; I find the standalone mode much easier to manage. – chrylis -cautiouslyoptimistic- Apr 10 '15 at 02:48
  • I'm about to explore doing that as well. Running a WAR inside an existing application server simplifies installation, but maybe that is a crutch to cast aside. – Justin Smith Apr 10 '15 at 04:26
  • 1
    Only if you take the existence of the application server as a given. In a legacy situation, that's probably the case, but new systems can start with an image-based setup that only needs a JVM and a single jar. – chrylis -cautiouslyoptimistic- Apr 10 '15 at 05:42
  • 1
    @JustinSmith I've answered a similar question here http://stackoverflow.com/questions/29106579/external-configuration-for-spring-boot-application/29122037#29122037 maybe this will help. – ci_ Apr 10 '15 at 10:10
  • 1
    The issue with '@PropertySource' for loading properties when deploying a war is that the logging properties will be ignored and the logging system will not work. Check this alternative [solution](http://stackoverflow.com/questions/31017064/how-to-externalize-spring-boot-application-properties-to-tomcat-lib-folder/31027378#31027378) – Daniel Mora Jun 26 '15 at 11:51

1 Answers1

4

SpringApplication is a public class so you can create an instance and set its properties before running your app (the static run() methods are just conveniences). You can also use SpringApplicationBuilder, which is what you get as a callback when you are running in an external container anyway. Using those APIs you can set default properties, and profiles, including the location (spring.config.location) and name (spring.config.name) of the application.properties file.

Note that (per the link you provided) you can also use JNDI variables in the container to override or set environment properties. That could also be useful if you are packing multiple apps into the same JVM.

Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • 1
    This works. As a sample of @Dave Syer suggestion you can check this [solution](http://stackoverflow.com/questions/31017064/how-to-externalize-spring-boot-application-properties-to-tomcat-lib-folder) – Daniel Mora Jun 26 '15 at 12:39