Spring Boot Profiles

Salitha Chathuranga
4 min readJul 13, 2022

--

Let’s implement environment based deployments

Hey developers! I have thought of starting an article series on Spring Boot framework. So, this will be the first out of those articles. I will not be touching the very basics, but essentials.

Let’s talk about Profiles in Spring Boot…

What are Profiles?

Spring framework provides the ability to group configuration properties into profiles, allowing us to activate them depending on the environment we deploy. Simply profile means a set of configurations.

But what is the real need???

Usually we deploy applications to different environments like DEV / STAGE(QA) / PROD…There are certain things that are changing based on the deploying environment. As an example, we can take database URL. We define this URL inside application.properties OR application.yml while we develop changes locally. According to that we can connect to the relevant env database.

// STAGE ENV URL
spring.datasource.url=jdbc:mysql://stage.db.server:3308/jpa-db
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
// PROD ENV URL
spring.datasource.url=jdbc:mysql://prod.db.server:3309/jpa-db
spring.jpa.generate-ddl=false
spring.jpa.show-sql=false
// DEV ENV URL
spring.datasource.url=jdbc:mysql://localhost:3306/jpa-db
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true

As you see in the above setup, URL and port can be changed. So, we cannot change this time to time and test..It’s tedious!!!

By default, Spring Boot takes application file URL and start the app. If you see the startup logs closely, You will see this log.

No active profile set, falling back to 1 default profile: "default"

Using profiles, we can define set of profiles per env, and bind any env to application using a configuration! No need to change the already defined configurations until any URL or any other is getting changed.

Let’s see how to do it…

Setup Profiles

We have to define env names first. For this, I will consider profile names as dev, stage and prod.

  • So we should create 3 properties or yml files for each env. Be careful about the naming conventions! The name must be application-env.properties or yml.
application.properties / yml
application-dev.properties / yml
application-stage.properties / yml
application-prod.properties / yml
  • Keep the default profile also. We need that to bind the active profile and to load common/unchanged configurations for all environments. These common configs will be same and constant in every env. Example is shown below. We can place such kind of configs in application.properties file.
spring.application.name=order-service
  • Let’s see how to bind active profile. Place the below line in application.properties file.
spring.profiles.active=stage

Now restart the application. See the startup logs…Did you notice a change? You should see this log now.

The following 1 profile is active: "stage"

Now database connection will be created using the URL and port included in application-stage.properties file.

But do not bind like this in production code branch, inside your default application.properties file. Do this only for local dev testing with any of the environments. Deployment scripts(DevOps side) will be responsible to deploy your code into the environments with relevant config file.

If you really need to maintain active profile in the code itself, you can go for env based code branches. The only change of these branches will be this.

spring.profiles.active=stage/dev/prod

For prod env, you can reserve master branch. Then all other env branches are having 1 commit ahead of master which contains the active profile change commit. Remember to rebase env branches regularly with the latest changes in master branch.

Deploy JAR with Profile

The above setup will be working while developing the application. But in the real world, we will be deploying a JAR mostly. So, we should have a way to run the JAR with a specified env. We can use the below terminal commands for that.

Method 1: Java System Property

java -Dspring.profiles.active=stage -jar appJarName.jar

Method 2: Environment Variable

export SPRING_PROFILES_ACTIVE=stage
java -jar appJarName.jar

Default Profile

Normally default profile is taken from the default configuration file. It can be application.properties OR application.yml…This is activated by default if we do not specify any active profiles.

Profile annotation

We can use this annotation to create any configuration like a bean at runtime based on the deployment environment. But usage of this annotation is not much recommended. We are breaking the general behavior of the application when we use profile annotation.

Look at the below config class which returns a bean.

@Configuration
class BeanClassConfig {
@Bean
@Profile("stage")
EnvBean envBean() {
return new EnvBean();
}
}

The factory method envBean() will only be called if the stage profile is active. If the profile is not active, there will be no EnvBean instance available in the application context.

ActiveProfiles annotation in testing

In testing, we may need to activate specific profiles. If we take an example, testing may require in memory H2 DB instead of a real MySQL DB. So, we can simply define an application-test.properties file and put DB

We need the below dependency to access “@ActiveProfiles” annotation.

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>

Use the annotation inside Test class like this..

@SpringBootTest
@ActiveProfiles("test")
class ProfileTest {
@Test
void test() {
// test something
}
}

But to enable this, you must disable spring.profiles.active in application.properties file!

This is the power of Profiles in Spring Boot guys! We can assign environment based configs using this setup. So, you can try this and implement in your daily coding also…

Let me know if there are any comments…

Bye Bye!!!

--

--

Salitha Chathuranga
Salitha Chathuranga

Written by Salitha Chathuranga

Associate Technical Lead at Sysco LABS | Senior Java Developer | Blogger

Responses (2)