I have two application property profiles dev and prod. I set the profile active in my application properties file as spring.profiles.active=dev
I want to dynamic load of my classpath properties file according to the active profile. so I want to inject the #Value annotation into my classpath variable as below:
#Configuration
#PropertySource({"classpath:application-#Value('${spring.profiles.active:}').properties"})
is it possible to do that??
You need to have one file application.properties where you have to specify the profile like this spring.profiles.active=dev
And than create dedicated files for each profile where you have specific configs.
application-dev.properties
application-uat.propertiea
Than you can use Value annotation and it will be picked automatically.
See this:https://dzone.com/articles/spring-boot-profiles-1
Related
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.
2 Options :
Generate the common/application.properties using configuration-maven-plugin and filter files for each environment. It is outdated now.
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)
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
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{}
If spring boot is run in override profile , can we have application-override.properties having properties like foo.baz that is not defined in application.properties ?
application.properties
foo.bar=1
application-override.properties
spring.profiles.include=default
foo.baz=1
That is correct. When you have new properties in application-override.properties and and the override profile is the active profile, then yes in your program the properties from application.properties as wel as application-override.properties is loaded.
Using spring.profiles.include=default in your override profile is not needed.
In the case of loading multiple specific profiles with same properties:
Also, in the context of property overriding with profiles, something to keep in mind when you have multiple active profiles and they contain the same property. The last profile in the list will be used.
Let's say you start up your program with mvn spring-boot:run -Drun.profiles=profile1,profile2
Both application-profile1.properties and application-profile2.properties
contains the property my.custom-property=x (for profile1) and my.custom-property=y (for profile2). The value of my.custom-property will be y, as that was the last profile in the provided profiles.
You can create configuration class for your custom profile and load the appropriate properties file in it like this:
#Configuration
#Profile("override")
#PropertySource("classpath:application-override.properties")
public class OverrideConfig {
}
This way, all the configuration you do in OverrideConfig (including taking properties from application-override.properties), will only load if override profile is enabled in application.properties like this:
spring.profiles.active=override
Long story short : Spring boot overrides values of properties with same name according to their evaluation order. But here you don't override any property, you add a new.
That is still simpler : Spring boot just adds it into the Spring Environment.
Just run the app by specifying this profile and makes sure that the properties are located in the locations expected by Spring Boot.
Example from a fat jar (Java system property) :
java -Dspring.profiles.active=override -jar foo.jar
Example from the source code (Maven property) :
mvn spring-boot:run -Dspring-boot.run.profiles=override
Yes, you can do this by simply add the profile name to the application.properties:
application-override.properties
Then you can load profile from the command line:
java -jar foo.jar --spring.profiles=override
source: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-change-configuration-depending-on-the-environment
Spring will load the application.properties first followed by any application-{profile}.properties.
Another option is to use yaml, and load everything into one file:
foo:
bar: 1
---
spring:
profiles: override
foo:
baz: 1
---
spring:
profiles: otherOverride
foo:
bar: 2
baz: 2
I have a Spring Boot multi-module maven project. I want my library module to handle its own properties.
So, in the library module:
src/java/resources/module-name/application.properties
src/java/resources/module-name/application-dev.properties
src/java/resources/module-name/application-prod.properties
I have a #Configuration class in that module with:
#PropertySource("classpath://module-name/application-dev.properties")
Obviously, this will only load the dev properties.
2 Questions:
1) How do I factor in #Profile in here so I don't have to create multiple configuration classes, each with its own #Profile. Is there a way to combine the annotations or parameterize them with something like application-${spring.active.profile}.properties?
2) How do I achieve the same behavior vis-a-vis application.properties file as I would have out of the box if these files were in the root of the classpath and picked up automatically by Spring? In other words, I'd like to place all the common properties into application.properties file and only the profile specific ones into application-dev.properties or application-prod.properties ones.
I have 3 yml files namely
application-default.yml -> default properties, should be available
in all profiles
application-dev.yml -> properties only for dev
profile
application-prod.yml -> properties only for prod profile
When I start my boot application by passing the -Dspring.profiles.active=dev,I am able to access the application-dev.yml specific properties.
But I cant get the properties defined in the application-default.yml files.
Following is my application-dev.yml file:
Spring:
profiles:
include: default
spring.profiles: dev
prop:
key:value
TL;DR
Just rename the application-default.yml file to application.yml and will work as you expect.
Explanation
According to the description in the docs, a file called application-{suffix}.yml is activated when you run your application with the profile which name matches with the suffix. In addition, the main application.yml is loaded by default so it's the perfect place to put common properties for all profiles. Alternatively, if you want to keep the name of your file as application-default.yml you can pass two profiles to your Spring Boot application:
-Dspring.profiles.active=default,dev
This way you will activate two profiles and both properties files will be loaded.
I was able to solve my problem, here is what I did.
Created a file application-common.yml, put the common properties there.
Then in the application-{env}.yml files I put this on the top.
spring:
profiles:
include: default
Since I dont need to ever load the default profile specifically, this works for me!!!
What I do is:
Put common settings in application.xml, and in this file add:
spring:
profiles:
active: dev, pro, xxx...
all the profiles you want to activate.
So that you just edit this file to switch environment.
Remember that external files procedes, so you can leave another application.xml outside of the WAR to activate dev/pro/... environment instead of editing this file every time. Be sure to check the documentation:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
I am working on a spring-boot application, I need your assistance on below scenario.
I have properties files for each environment something like application-dev.properties, application-prod.properties etc. Is there way that my application can load environment specific properties file by using spring #Profile annotation.
Please help.
You don't need to use #Profiles annotation at all. Just use
#ConfigurationProperties(locations = "classpath:myapp-${environment.type}.properties")
and define environment type via system property. E.g. via command line -Denvironment.type=dev.
#Profile is not for loading environment specific properties file. It is for specifying profile of a bean. For example,
#Profile("dev")
#Component
class Foo {
}
It means the bean of Foo is only available when the active profiles include dev. Or the opposite #Profile("!dev"), which means the bean is available when dev is not an active profile.
So for loading environment specific properties file, since it is spring-boot, you can just specify the active profiles. There are several ways to specify the active profiles.
Environment variable: SPRING_PROFILES_ACTIVE=dev,prod
command line argument: java -jar app.jar --spring.profiles.active=dev,prod
Programmatically : SpringApplicationBuilder(...).properties("spring.profiles.active=dev,prod).run(...)
Default application.properties or yaml: spring.profiles.active:dev, prod