Table of Contents
What have we learned so far,
Part 1 – Spring Rest Advance : Input / Bean Validations
In this post, we discussed the steps to validate the input bean in Spring Rest.
Part 2 – Spring Rest Advance : Rest Documentation with Swagger 2
In this post, we discussed the steps to configure swagger to do the documentation for Spring Rest services
Part 3 – Spring Rest Advance : Spring Boot with H2 DB
In this post, we discussed the steps to configure and use H2 db in spring boot
Part 4 – Spring Rest Advance : Spring Rest Versioning
In this post we discussed the different ways to do the Rest versioning.
Part 5 – Asynchronous Spring Service With @Async And @EnableAsync
In this post we discussed the way to execute a code asynchronously
What are Profiles in Spring?
Development environment- Where the developer develops and test the code.
Test Environment – Where the Tester tests the code
UAT Environment- Where the end user tests the code before moving it to production
Production Environment – Where the actual end user uses the website
Each environment have their configuration settings like mail server on Dev, Test, UAT and production may vary as the developer don’t want to use the production or UAT mail server for his local development.
Profiles are bunch of environment specific properties which gets activated based on their profile names.
How to implement Profiles in Spring Boot?
Spring Profiles provide a way to segregate parts of your application configuration and make it be available only in certain environments. Any @Component, @Configuration or @Bean can be marked with @Profile to limit when it is loaded.
Our example – We will write a controller which requirers the MailServer and the configuration for this mail server depends on the environment on which the application is running. Like Dev environment may have the mail server host as dev-host, production will have the mail host as prod-host and all.
Lets see how to use profile with Spring Boot
1. Profiles with property files placeholders
We make properties files for each environment and set the profile in the application accordingly, so it will pick the respective properties file. Don’t worry, we will see how to set it up.
application.properties – Hold the common properties across the environments
#Common Properties to all environment #Current profile name spring.profiles.active=prod spring.application.name=Spring Profiles onlyfullstack.message=This is the primary Application Property for ${spring.application.name}
application-dev.properties – Hold the properties related to dev environments
# Development Environment Settings onlyfullstack.message= This is the property file for the ${spring.application.name} specific to Dev Environment onlyfullstack.mail.server=dev-server onlyfullstack.mail.username=dev-user onlyfullstack.mail.password=dev-password
application-test.properties – Hold the properties related to test environments
# Test Environment Settings onlyfullstack.message= This is the property file for the ${spring.application.name} specific to Test Environment onlyfullstack.mail.server=test-server onlyfullstack.mail.username=test-user onlyfullstack.mail.password=test-password
application-prod.properties – Hold the properties related to production environments
# Production Environment Settings onlyfullstack.message= This is the property file for the ${spring.application.name} specific to Production Environment onlyfullstack.mail.server=prod-server onlyfullstack.mail.username=prod-user onlyfullstack.mail.password=prod-password
Lets write a bean to read these value based on the environment.
Here @ConfigurationProperties will append the onlyfullstack.mail as prefix to each variable name and try to find the property key in the properties file.
package com.onlyfullstack.springprofiles.model; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("onlyfullstack.mail") public class MailSettings { private String server; private String username; private String password; public String getServer() { return server; } public void setServer(String server) { this.server = server; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "MailSettings{" + "server='" + server + ''' + ", username='" + username + ''' + ", password='" + password + ''' + '}'; } }
2. Profiles with Stereotype Annotations
We can use @Profile annotation with stereotype annotations(@Component / @Service / @Repository / @Bean / @Configuration). Lets use the @Profile annotation to create the ConfigServer object.
ConfigServer
package com.onlyfullstack.springprofiles.service; public interface ConfigServer { String setup(); }
DevConfigServer
package com.onlyfullstack.springprofiles.service; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @Profile("dev") @Service public class DevConfigServer implements ConfigServer { @Override public String setup() { return "Calling Dev Copnfig Server"; } }
TestConfigServer
package com.onlyfullstack.springprofiles.service; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @Profile("test") @Service public class TestConfigServer implements ConfigServer { @Override public String setup() { return "Calling Dev Test Server"; } }
ProdConfigServer
package com.onlyfullstack.springprofiles.service; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @Profile("prod") @Service public class ProdConfigServer implements ConfigServer { @Override public String setup() { return "Calling Prod Copnfig Server"; } }
ProfileController
package com.onlyfullstack.springprofiles.controller; import com.onlyfullstack.springprofiles.model.FinalResponse; import com.onlyfullstack.springprofiles.model.MailSettings; import com.onlyfullstack.springprofiles.service.ConfigServer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ProfileController { @Autowired ConfigServer configServer; @Autowired MailSettings mailSettings; @GetMapping("/welcome") public FinalResponse getDataBaseConnectionDetails() { return new FinalResponse(configServer.setup(), mailSettings); } }
Lets run our app and hit the below url and we can see that the MailSettings have all production related settings and Config Message is from Production Configuration.
http://localhost:8080/welcome
How to Activate Profile?
1. JVM System Parameter
The profile names can also be passed in via a JVM system parameter. The profile names passed as the parameter will be activated during application start-up:
-Dspring.profile.active=prod
2. Environment Variable
You can change the profile dynamically whole running the application by passing the –spring.profiles.active=prod to the mvn command as below:
java -jar spring-profiles-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
3. Programmatically via WebApplicationInitializer interface
In web applications, WebApplicationInitializer can be used to configure the ServletContext programmatically.
It’s also a very handy location to set our active profiles programmatically:
@Configuration public class MyWebApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { servletContext.setInitParameter( "spring.profiles.active", "prod"); } }
4. Programmatically via ConfigurableEnvironment
You can also set profiles directly on the environment:
@Autowired private ConfigurableEnvironment configEnv; configEnv.setActiveProfiles("prod");
Source Code
Download source code of Spring Rest Advance Topics from below git repository :
spring-rest-advance-topics
Spring Rest Advanced Tutorial
https://www.onlyfullstack.com/spring-rest-advanced-tutorial/
Lets go to our next tutorial where we will discuss below point
7. Best practices for Spring Rest
– How To Do @Async in Spring Service
– What is the need of Asynchronous?
– How to use @Async and @EnableAsync in Spring Boot
Blog URL – Part 7 – Best practices for Spring Rest