4

My spring boot application has below properties files.

src/main/resources/config/DEV/env.properties
mail.server=dev.mail.domain

src/main/resources/config/QA/env.properties
mail.server=qa.mail.domain

src/main/resources/config/common/env.properties
mail.url=${mail.server}/endpoint

Is it possible to load "common/env.properties" so that it's placeholders will be resolved using the given environment specific properties file. For DEV environment, we want the placeholders in "common/env.properties" to be resolved using values from "DEV/env.properties".

There are answers about how to load multiple properties files and profile based loading but could not find an answer for this particular use case.

Thanks in advance.

Anooj VB
  • 41
  • 1
  • 1
  • 5

3 Answers3

3

2 Options :

  1. Generate the common/application.properties using configuration-maven-plugin and filter files for each environment. It is outdated now.
  2. Use application-<env>.properties for each environment and pass the -Dspring.profiles.active=<env> as VM option in application start up. Spring will automatically take the property from correct file.

In option 2, you will be overwriting whatever is present in application.properties with application-.properties. So you dont have to add only the properties which you need to change per environment.

for eg:

Your application.properties can have

logging.level.root=WARN
logging.level.org.apache=WARN
logging.level.org.springframework=WARN

Your application-dev.properties can have

logging.level.org.springframework=DEBUG

which means, when you are starting application using dev profile, spring takes

logging.level.root=WARN
logging.level.org.apache=WARN
logging.level.org.springframework=DEBUG

edit :

Also, you can try something like below on your class. (Spring will overwrite value in config.properties with values from config-dev.properties). ignoreResourceNotFound will make sure, application will still start with default values even if the corresponding file is not found.

@Configuration
@PropertySource("classpath:config.properties")
@PropertySource(value = "classpath:config-${spring.profiles.active}.properties", ignoreResourceNotFound = true)
Abbin Varghese
  • 2,422
  • 5
  • 28
  • 42
  • Thanks. I'll try this and update. Checking out of curiosity, Is there any way to use /common/env.properties instead of application.properties to store default values. – Anooj VB Feb 27 '19 at 10:33
  • You can add the env.properties files to class path. Check this out : https://stackoverflow.com/questions/44499306/how-to-read-application-properties-file-without-environment-variable/50951259#50951259 – Abbin Varghese Feb 27 '19 at 13:08
0

You can achieve this by declaring a property source on a class configuration and setting up an environment variable in the path :

@PropertySource({ "classpath:config/${env}/env.properties" })
@Configuration
public class config{}

And then you launch the spring boot app with the command line variable -env=dev

UPDATE

You can use @PropertySources annotation to load several properties.

 @PropertySources({
    @PropertySource("classpath:config/${env}/env.properties"),
    @PropertySource("classpath:config/common/env.properties")
  })
  public class config{}
Andrianekena Moise
  • 1,018
  • 7
  • 16
  • Thanks. How will /common/env.properties be loaded? We would need both /common/env.properties and {env}/env.properties loaded. – Anooj VB Feb 27 '19 at 10:30
  • Please see my update in the answer. You can load several properties using `@PropertySources` annotation. So you can load both /common/env.properties and {env}/env.properties at the same time. If it was helpful, thanks to mark the answer as response. – Andrianekena Moise Feb 27 '19 at 10:49
  • Thanks, if we load this way, will placeholders in /common/env.properties be resolved with values from {env}/env.properties? – Anooj VB Feb 27 '19 at 11:58
  • as there is no placeholders in this path /common/env.properties, there is no resolution. – Andrianekena Moise Feb 27 '19 at 12:29
  • Not in the path, but there are placeholders in the content of /common/env.properties. For example; mail.url=${mail.server}/endpoint. We need ${mail.server} be resolved with value from the content of {env}/env.properties. /DEV/env.properties contains mail.server=dev.mail.domain – Anooj VB Feb 27 '19 at 18:15
0

You can add resources/application.yml file where you can have multiple profiles in one File. MultiProfile Yaml e.g.here are two different profiles 'dev' and 'qa' with different applicationNames 'DEV' and 'QA' and one defaultName 'Default'

spring:
  application:
    name: Default
  profiles:
    active: qa

---
spring:
  profiles: dev
  application:
    name: DEV
---
spring:
  profiles: qa
  application:
    name: QA