Application properties, e.g. the database connection parameters, shouldn’t be hard-coded in our applications. They should instead be put externally, say in properties/YML files, and injected into the application.

Spring Boot has multiple ways to handle this. It’s detailed in the reference material, but me share some key steps that I follow.

1) Place all the properties (or .yml) files in /src/main/resources/config folder

Spring Boot, by default, looks for properties files either in classpath root, i.e. /src/main/resources, or inside a config sub-folder. I personally prefer the config sub-folder.

2) Use Spring profiles to segregate properties

Some of the application properties would be same across environments, while some would vary. For example, multipart.enabled=false could be same across all environments, whereas spring.datasource.url could vary on development, test and production environments.

Spring profiles help segregating these. Specifically, we could put environment specific properties in files like application-dev.properties, application-prod.properties etc., and then define a property like spring.profiles.active=dev, to tell Spring which environment is’s running on. (Or, we could simply leave out defining spring.profiles.active, in which case the default profile will be active.)

3) Hide confidential properties

Some of the properties, like the database password of the production database, should not be visible to all the developers. So, I won’t put those in the application-prod.properties file inside our project. Instead, I’d have those in an application-prod.properties in the directory where the JAR will be deployed, or in a config sub-directory therein. These external files take precedence over those in the project.

Alternatively, we can define environment variables (in the deployment machine) corresponding to these properties, replacing dots with underscores. For example, to set spring.datasource.password, you can set an environment variable spring_datasource_password=top-secret. Environment variables take precedence over configuration files. They are a good solution, particularly on PaaS like Pivotal Cloud Foundry, where creating external properties files would not be permitted.

You can override spring.active.profile in production or test using the same methods that we discussed above. When writing test cases, the @ActiveProfiles annotation comes handy though, as below:

@SpringBootTest(webEnvironment=RANDOM_PORT)
@ActiveProfiles("itest")
public class MyTests {

Hope this was helpful! Read my next post for how to go further and use Spring Cloud Config, particularly when you have multiple applications, e.g. in a microservice architecture.