Spring Environment and Spring Profiles

Introduction

This is a series and it would make a lot of sense if read in a sequence. You can find all the posts under the heading “Spring Beginners to Professionals“. In real enterprise scenario you run your application in different environments. For e.g.: dev, testing, stage, production etc. And it is logical to have different set of properties for each of these environment.

For e.g. a developer might want to use an in memory database configuration for his unit testing, whereas a QA might want to test it against a test database. Business users may want to test it against a stage database which has production dump and the live customer will use it against the real production database. All these might be true for other properties as well.

For e.g.: If our application communicates with a third party web service and they expose two separate endpoints one for testing and the other for production, then our application must be configured against these URLs depending the scenario if our application is running in production or any of the pre-production  environments.

Spring Environment and Spring Profiles

The Spring Environment represents a logical environment in which the application is running. The environment manages two key aspects in Spring applications.

Profiles

A profile can be considered as a named categorization or group of bean definitions which should be managed by the application context and made available if we set this particular profile as active. One or more profiles can be active at a time, of course there should be no conflicts while doing so.

Each bean can be assigned one or more profile names at the time of configuration, but mostly we do it for the ones which are different for different environments. If no profile name is present on a bean, that is injected in all the environments.

For e.g. A developer would like to have a HSQL in memory database to run his unit tests and hence, he can set the dev profile as active and mark the datasource’s profile as dev. Here is a similar example.

Annotation Driven Configuration

Bean Definitions

Below we define an interface AppDataSource, which is implemented by two beans, InMemoryDataSource with a “dev” profile and a QADataSource with a “qa” profile. For the above configuration, with active “dev” profile, the only bean which will be registered is the InMemoryDataSource, the QADataSource won’t be registered.

Sample App Runner

Once you run this application sample, the console output would be inMemoryDataSource. Yes I understand, in a normal scenario Spring would have thrown an error saying there are more than one qualifying beans. However, in this case, due to the Profiles infrastructure, this is easily handled.  If you now change the activeProfiles to qa, you will see a console output qaDataSource. 

On a side note, the active profile information can be passed using the command line arguments or JVM arguments. In case of a web application, we can specify the active profile in the web.xml

Properties

The other key aspect is Properties. In the previous post we learnt the importance of Properties and how they provide the much needed flexibility to an application in more ways than one. The PropertyResolver is the parent of Environment, it offers the capabilities to fetch properties and perform queries related to them. It also exposes APIs to resolve properties based on placeholders, so that you can use a placeholder in the application and it can automatically replace the actual value for that property if found.

Summary

The Spring Environment Abstraction is a great and easy to use mechanism. Specially the Profiles part. The same application can contain multiple versions of beans and even configurations. Let me know below in the comments , if you need a more detailed explanation and example.

Stay Connected