Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – Spring Top – Temp – Non-Geo (Lightrun)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

Table of Contents

1. Configuration Must Be Environment Specific

Configuration must be environment specific – that's just a fact of life. If that weren't the case, then it wouldn't be configuration and we would just hardcode values in code.

For a Spring application there are several solutions you can use – from simple solutions all the way to uber-flexible, highly complex alternatives.

One of more common and straightforward solutions is a flexible use of properties files and the first class property support provided by Spring.

As a proof of concept, for the purposes of this article, we'll take a look at one specific type of property – the database configuration. It makes perfect sense to use one type of database configuration for production, another for testing and yet another for a dev environment.

2. The .properties Files for Each Environment

Let's start our Proof of Concept – by defining the environments we want to target:

    • Dev
    • Staging
    • Production


Next – let's create 3 properties files – one for each of these environments:

  • persistence-dev.properties
  • persistence-staging.properties
  • persistence-production.properties

In a typical Maven application, these can reside in src/main/resources, but the wherever they are, they will need to be available on the classpath when the application is deployed.

An important sidenote – having all properties files under version control makes configuration much more transparent and reproducible. This is in opposition to having the configs on disk somewhere and simply pointing Spring to them.

3. The Spring Configuration

In Spring, we'll include the correct file based on the environment:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"

         classpath*:*persistence-${envTarget}.properties" />


The same can of course be done with Java configuration as well:

@PropertySource({ "classpath:persistence-${envTarget:dev}.properties" })

This approach allows for the flexibility of having multiple *.properties files for specific, focused purposes. For example – in our case, the persistence Spring config imports the persistence properties – which makes perfect sense. The security config would import security related properties and so on.

4. Setting the Property in Each Environment

The final, deployable war will contain all properties files – for persistence, the three variants of persistence-*.properties. Since the files are actually named differently, there is no fear of accidentally including the wrong one. We will set the envTarget variable and thus select the instance we want from the multiple existing variants.

The envTarget variable can be set in the OS/environment or as a parameter to the JVM command line:


5. Testing and Maven

For integration tests that need persistence enabled – we'll simply set the envTarget property in the pom.xml:


The corresponding persistence-h2_test.properties file can be placed in src/test/resources so that it will only be used for testing and not unnecessarily included and deployed with the war at runtime.

6. Going Further

There are several ways to build additional flexibility into this solution if needed.

One such way is to use a more complex encoding for the names of the properties files, specifying not just the environment in which they are to be used, but also more information (such as the persistence provider). For example, we might use the following types of properties: persistence-h2.properties, persistence-mysql.properties or, even more specific: persistence-dev_h2.properties, persistence-staging_mysql.properties, persistence-production_amazonRDS.properties.

The advantage of such a naming convention – and it is just a convention as nothing changes in the overall approach – is simply transparency. It now becomes much clearer what the configuration does only by looking at the names:

  • persistence-dev_h2.properties: the persistence provider for the dev environment is a lightweight, in-memory H2 database
  • persistence-staging_mysql.properties: the persistence provider for the staging environment is a MySQL instance
  • persistence-production_amazon_rds.propertie: the persistence provider for the production environment is Amazon RDS

7. Conclusion

This article discusses a flexible solution for doing environment specific configuration in Spring. An alternative solution using profiles can be found here.

The implementation of the solution can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Generic footer banner
Comments are closed on this article!