Spring Boot Profiles and Configuration Management Example


In this tutorial, we’ll learn how to configure and set profiles using Spring Boot. Every enterprise application has many profiles (environments) like development, testing, UAT, production, etc and each environment have settings specific to them.

In Spring Boot application managing all this information is handled by one place. Let’s see below how?

What is Profile?

Spring Profiles provide a way to segregate parts of your application configuration and make it be available only in certain environments. These environments host-specific configurations called Profiles.

For example, the DEV environment will run on the port 8080 and will connect with spring_dev database, similarly, the PROD will run on the port 8082 and connect with spring_prod database with their username and password.

What we’ll build?

In this example, we will create a brand new Spring Boot application and set up the connections settings of each profile, print them on the console and activate them from single hook i.e. application.properties file.

Let’s begin and checkout what is the project structure and technologies used step by step.

What you’ll need

  • About 15 minute
  • A favourite text editor or IDE
  • JDK 1.8 or later
  • Gradle 4+ or Maven 3.2+
  • MySQL database
  • You can also import the code straight into your IDE:
    • Spring Tool Suite (STS)
    • Eclipse
    • IntelliJ IDEA

Dependencies Required

Well, there is no specific dependencies are required for Profiles, simple spring boot starter is enough and you can add anything specific to your project requirement.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>org.websparrow</groupId>
	<artifactId>spring-boot-profiles</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-profiles</name>
	<description>spring-boot-profiles</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Project Structure

The final project structure of our application in STS 4 IDE will look like as follows:

Spring Boot Profiles and Configuration Management Example

Setup the Profiles

Suppose we have a Spring Boot application which needs to be deployed on DEV and PROD environment with different settings/configuration. For each environment, we have two create separate properties file inside the src/main/resources directory:

DEV environment will run on port 8080 and uses the spring_dev database:

application-development.properties
# -------  DEV ENVIRONMENT SETTINGS -------- #

server.port=8080
profile.desc=This property file is specific to DEVELOPMENT environment.
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/spring_dev
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true

Similarly, the PROD environment will run on port 8082 and uses the spring_prod database:

application-production.properties
# -------  PROD ENVIRONMENT SETTINGS -------- #

server.port=8082
profile.desc=This property file is specific to PRODUCTION environment.
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/spring_prod
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true

The naming convention of properties file for different profiles have to be named in the format applications-[profile].properties.

Print the Active Profile Settings

Create DatabaseConfig class and annotate this class with @Configuration and @ConfigurationProperties annotation.

DatabaseConfig.java
package org.websparrow.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
@ConfigurationProperties("spring.datasource")
public class DatabaseConfig {

	// Generate Getters and Setters...
	private String url;
	private String username;

	@Profile("development")
	@Bean
	public String developmentConnectionStrings() {
		System.out.println("DB connection for 'DEVELOPMENT'");
		System.out.println(username);
		System.out.println(url);
		return "DEV Enviroment Connected!";
	}

	@Profile("production")
	@Bean
	public String productionConnectionStrings() {
		System.out.println("DB connection for 'PRODUCTION'");
		System.out.println(username);
		System.out.println(url);
		return "PROD Enviroment Connected!";
	}
}

Any @Component, @Configuration or @ConfigurationProperties can be marked with @Profile to limit when it is loaded.

We have used the @Profile("development") to let the system know that this is the BEAN that should be picked up when we set the application profile to DEV. The other beans will not be created at all.

How to Activate Profile?

Well, the question is how Spring Boot application know that is DEV, TESTING, PROD, UAT, etc and which configuration settings need to be activated? To let the application know to use this configuration can be triggered by application.properties file.

application.properties
# Set current active profile
spring.profiles.active=development

Controller

ProfileController return profile description of active profile form its configuration file.

ProfileController.java
package org.websparrow.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProfileController {

	@Value("${profile.desc}")
	private String profilDesc;

	@GetMapping("/profile")
	public String profile() {

		return profilDesc;
	}
}

Run the application

The SpringBootProfilesApp class contains the main method and responsible to start the application.

SpringBootProfilesApp.java
package org.websparrow;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootProfilesApp {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootProfilesApp.class, args);
	}
}

Test the application

To test the application, start the Spring Boot application by executing the above class and during the startup, it will print the settings and server port on the console:

console log
2019-11-30 19:55:44.967  INFO 3268 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2019-11-30 19:55:45.005  INFO 3268 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
DB connection for 'DEVELOPMENT'
root
jdbc:mysql://localhost:3306/spring_dev
2019-11-30 19:55:45.207  WARN 3268 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-11-30 19:55:45.494  INFO 3268 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-11-30 19:55:46.024  INFO 3268 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-11-30 19:55:46.029  INFO 3268 --- [           main] org.websparrow.SpringBootProfilesApp     : Started SpringBootProfilesApp in 15.516 seconds (JVM running for 18.088)

Apart from this, we can also check the active profile by hitting http://localhost:8080/profile URL on web browser address bar and it will return the profile description from the active profile:

This property file is specific to DEVELOPMENT environment.

Note: Server port will be differ based on the active profile. Change accordingly.

References

  1. Spring Boot Profiles
  2. Profile-specific Properties

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.