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.
<?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:
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:
# ------- 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:
# ------- 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.
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.
# Set current active profile
spring.profiles.active=development
Controller
ProfileController
return profile description of active profile form its configuration file.
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.
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:
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.
Download Source Code: spring-boot-profiles-and-configuration-management-example.zip