Spring Configuration

A standard Spring Boot application will have an application.properties file with any required settings in, however this file will get compiled into your JAR file and also the values may end up in your version control repository, which is not what you want from a security perspective. Fortunately, there are other ways to deal with this kind of configuration.

Configuration can either be "external", set with command line parameters, JNDI stores or environment variables or "internal" using servlet parameters, property files or Java configuration, however these internal things could point to external sources. Generally external settings override internal ones but not always. The order of precedence is as follows, where items higher up the list (a lower number) override any values set further down:

  1. Command Line Arguments
  2. SPRING_APPLICATION_JSON Arguments
  3. Servlet Parameters
  4. JNDI
  5. Java System Properties
  6. OS Environment Variables
  7. Profile Properties
  8. Application Properties
  9. @PropertySource Annotations
  10. Default Properties

If you want to better understand some of these and how to use them, like SPRING_APPLICATION_JSON for example, then see Core Features - Externalized Configuration for details.

The recommendation is to pick one external source and one internal source and just use these. For example use Application Properties file for defaults and non-sensitive things and then use Operating System Environment Variables for passwords and to override things.

IntelliJ IDEA, is very helpful with Spring configuration, offering auto-complete in the application.properties file but also the "Edit Configurations" option allows you to set options for running within IntelliJ. Here you can specify "VM Options" but they need a "-D" prefix, or you can do this in the Ultimate edition via "Override parameters" in the "Spring Boot" section. There is also an option for Environment Variables. You can see already it is easy to create confusion and hence why it is a good idea to stick to one external source and one internal source of configuration.

Another option is to reference external sources from internal ones. For example, in the application.properties file you can reference environment variables. So whereas you might have had this:

server.port=9090

You can replace it with the following:

server.port=${THE_PORT}

This assumes you have defined an environment variable called THE_PORT with a suitable value. I can see how this is useful but personally it does seem rather confusing, in my opinion.

Keep Up To Date

One of the challenges of Spring is keeping up to date with releases. However one handy utility is the "properties migrator" You can simply add it to your Maven pom.xml file like this:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
</dependency>

When you next run your Spring Boot application this dependency will log any old or deprecated properties that you have set and tell you where you did that and what the replacement should be. Do make sure you remove this before you release your code, as it does have quite a performance hit to startup and is really only for development use.

Configuration Options

For a list of settings that can be changed, see Common Application properties, however do note this is for the current "snapshot" of Spring Boot, it might be better to go to Spring Boot and jump into the Reference Documentation for the version you are using.

Custom Options

It is easy to configure and work with your own custom options, they can be defined in your Properties file or YAML file, or any of the options listed above. Firstly you will need something like the following in your application.properties file:

demo.app.version=1.0.0
demo.app.author=Geoff Lawrence

Then in your Java code just use them like this:

@Value("${demo.app.version}")
private String appVersion;

@Value("${demo.app.author}")
private String appAuthor;

As you can see it is the name in the annotation that needs to match the property name, the Java Class Field can be whatever you want.

Application Properties

These can be specified in either application.properties or application.yml, however if you have both then the .properties file takes precedence over the .yml file. There is no right or wrong choice between Properties and YAML, some find YAML's tree like structure easier, others prefer the old properties style, both work. I would just recommend picking one and sticking with it.

A properties file to set the port for Spring Boot to listen on, to turn the Spring banner off and configure some logging levels would look like this:

server.port=52112
logging.level.org.springframework=WARN
logging.level.com=WARN
spring.main.banner-mode=off

The YAML version of the same settings is this:

server:
  port: 52112
logging:
  level:
    org.springframework: WARN
    com: WARN
spring:
  main:
    banner-mode: off

Useful Settings

Documenting some settings I have used and found useful, clearly the documentation is the definitive source on this.

Settings Description
debug=true Turn Spring debugging on
management.endpoints.web.exposure.include=* Enable all Spring actuators over web

Profile Properties

Spring has the option where you can specify an environment or profile. This is useful for having different options for Production as opposed to Development, for example you will probably want different levels of logging in the different environments. You can specify a "prod" profile by setting spring.profiles.active=prod, then you need to create a file called application-prod.properties (or .yml), hopefully you can see the two references to "prod" and see that these will need to match. As these Profile files are in the resources of the JAR and hence built in it is probably best to specify the profile with an OS Environment Variable, on the Command Line, or via Java System Properties.

The Profile configuration files take precedence over any Application configuration files and also note that as for Application Properties the .properties file takes precedence over the .yml file.

Troubleshooting

With configuration properties getting increasingly complex it is hard to diagnose where these settings are coming from. Spring Boot 2.4 introduced the ability to use imports in properties files, adding more complexity. This is where the configprops actuator comes in. You should be able to access this via http://localhost:8080/actuator/configprops, presuming you have the actuators enabled. You might also find http://localhost:8080/actuator/env useful as well.

Useful Articles

Summary

As you can see this area can get quite complex and there is more than I have covered here. The important thing to remember is not to hard code stuff in files that you might want to change, like the Database Connection URL, or sensitive stuff like passwords as you do not want these in your version control system or have all the developers knowing the username and password for production.