I am working on an Spring web application in where I need to have variable's that will have different value in local environment and other value in production environment.
For Eg (file upload directory). My file upload directory is different for local and prod environment.
Currently I am doing it by checking the host name (if 'localhost' then A else B) and taking this approach. By there is another way to solve this problem via property files, Does anybody provide me pointers to how to approach that?
Properties files are used to keep 'N' number of properties in a single file to run the application in a different environment. In Spring Boot, properties are kept in the application. properties file under the classpath. Note that in the code shown above the Spring Boot application demoservice starts on the port 9090.
Environment-Specific Properties File. If we need to target different environments, there's a built-in mechanism for that in Boot. We can simply define an application-environment. properties file in the src/main/resources directory, and then set a Spring profile with the same environment name.
You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration.
You can load properties based on the current spring profile or profiles. To set a spring profile I mostly set a system property named spring.profiles.active
to the desired value e.g. development
or production
.
The concept is pretty simple. Read the currently active profile from the system property. Build the filename and load the properties file using a PropertySourcesPlaceholderConfigurer
. Using the PropertySourcesPlaceholderConfigurer
will make it easier the access those properties through @Value
annotations. Note that this examples assumes one profile is active. It may need some extra care when multiple profiles are active.
Java based configuration
@Configuration public class MyApplicationConfiguration { @Bean public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { String activeProfile = System.getProperty("spring.profiles.active", "production"); String propertiesFilename = "app-" + activeProfile + ".properties"; PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setLocation(new ClassPathResource(propertiesFilename)); return configurer; } }
You could also import multiple configuration classes annotated with @Profile
. Spring would select which configuration to use based on the currently active profiles. Every class could add it's own version of PropertySourcesPlaceholderConfigurer
to the application context.
@Configuration @Import({Development.class, Production.class}) public class MyApplicationConfiguration {} @Configuration @Profile("development") public class Development {} @Configuration @Profile // The default public class Production {}
As Emerson Farrugia stated in his comment the @Profile
per class approach is a bit drastic for selecting a PropertySourcesPlaceholderConfigurer
. Annotating a @Bean
declaration would be much simpler.
@Configuration public class MyApplicationConfiguration { @Bean @Profile("development") public static PropertySourcesPlaceholderConfigurer developmentPropertyPlaceholderConfigurer() { // instantiate and return configurer... } @Bean @Profile // The default public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { // instantiate and return configurer... } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With