Table of Contents
How to read different properties file based on Spring Profile in a Spring MVC project
Introduction
This tutorial aims towards providing a solution for selecting properties file based on the profile injected for a Spring MVC application at run time.
Technologies used
- Spring 3.1
- Java 8
How to inject Spring profile
Spring profiles can be passed as an environment variable like
-DSPRING_PROFILES_ACTIVE="dev" where dev is the profile name
- If you are using Eclipse You can add an environment variable say in local tomcat server by doing Right click on Your_Project -> Run AS Config –> Apache tomcat -> VM arguments add -DSPRING_PROFILES_ACTIVE=”dev”, as shown below.
- If you are using Docker you can have a look at this link.
How to get the Spring Profile within servlet context
If you have set the profile on the server and want it to retrieve it within your application you can use System.getProperty or System.getenv methods.
Here is the code which fetches the profile and defaults it to a local profile, if no profile has been found.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | private static final String SPRING_PROFILES_ACTIVE = "SPRING_PROFILES_ACTIVE"; String profile; /** * In local system getProperty() returns the profile correctly, however in docker getenv() return profile correctly * */ protected void setSpringProfile(ServletContext servletContext) { if(null!= System.getenv(SPRING_PROFILES_ACTIVE)){ profile=System.getenv(SPRING_PROFILES_ACTIVE); }else if(null!= System.getProperty(SPRING_PROFILES_ACTIVE)){ profile=System.getProperty(SPRING_PROFILES_ACTIVE); }else{ profile="local"; } log.info("***** Profile configured is ****** "+ profile); servletContext.setInitParameter("spring.profiles.active", profile); } |
Also if you are using Java configuration for spring that is, extending a class from WebApplicationInitializer you need to set the profile in servlet context by using setinitParamter() method which has been added as the last line in above method.
1 2 3 | servletContext.setInitParameter("spring.profiles.active", profile); |
Picking the right property file based on profile
If you have come this far without any problems then the next step is to create a different properties file for different environments.
You might want to create different properties files in the format like application-{profile}.properties, so you might end up creating something like this.
To access the application-dev.properties, say now you will need to use
@Profile("dev") at the class level
The following code will fetch the application-dev.properties and common.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Configuration @Profile("dev") public class DevPropertyReader { @Bean public static PropertyPlaceholderConfigurer properties() { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); Resource[] resources = new ClassPathResource[] { new ClassPathResource("properties/common.properties"), new ClassPathResource("properties/application-dev.properties") }; ppc.setLocations(resources); ppc.setIgnoreUnresolvablePlaceholders(true); return ppc; } } |
For accessing say application-prod.properties you have to use @Profile("prod") at class level
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Configuration @Profile("prod") public class ProdPropertyReader { @Bean public static PropertyPlaceholderConfigurer properties() { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); Resource[] resources = new ClassPathResource[] { new ClassPathResource("properties/common.properties"), new ClassPathResource("properties/application-prod.properties") }; ppc.setLocations(resources); ppc.setIgnoreUnresolvablePlaceholders(true); return ppc; } } |
Access the properties in controller
To access the properties in controller, all you have to do is to use the @Value annotation
1 2 3 4 | @Value("${application.message}") String message; |
Hope,it helps !!