I would like to setup 3 profiles in spring boot: production,development,test with using an external config file.
Application class:
#SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run( Application.class, args );
}
}
AppConfig class:
#Configuration
#PropertySources({
#PropertySource("config/application.yml"),
#PropertySource(value = "file:${external.config}")
})
#ConfigurationProperties
public class AppConfig {
}
config/application.yml:
---
spring.profiles: production
endpoints.enabled: false
---
spring.profiles: development,test
endpoints.enabled: true
info.version: #project.version#
info.test: Test dev or test
info.profile: ${spring.profiles.active}
---
external.config: ${user.home}/.myapp/application.properties
.myapp/application.properties:
spring.profiles.active=production
info.version=5
The output of spring-boot-actuator /info
{
version: "5",
test: "Test dev or test",
profile: "production"
}
Expected output:
404 because of the endpoints.enabled: false
The spring-boot-actuator /env
spring.profiles.active: "production"
You should probably prefix the application.yml file with classpath:
In any case, why not just use the spring profile to drive configuration directly in java configuration? IMO, this would be cleaner and would make your properties more type-safe & re-factor friendly and not prone to spelling mistakes.
UPDATE:
According to the docs, you can't load yml files with the #PropertySource annotation:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-yaml-shortcomings
So if you need to use files, you'll need to use plain properties files. You could use property-specific application properties files shown here.
In addition to application.properties files, profile-specific
properties can also be defined using the naming convention
application-{profile}.properties.
Related
everyone。When I was writing junit, I found that #ActiveProfiles corresponds to my resource directory。
I don’t understand how spring boot loads resource files,And why if I don’t specify #ActiveProfiles which application file is read by default?
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#SpringBootTest(classes = Application.class)
#ActiveProfiles("test")
public class NewTutorGroupIaoTest {
}
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#SpringBootTest(classes = Application.class)
#ActiveProfiles("test")
public class NewTutorGroupIaoTest {
}
project directory:
project
- src
- main
- java
- resource
- test
- java
- resource
If you mark classes with #Profile("test"), you can ensure they're loaded (into the ApplicationContext) by activating the test profile - either with #ActiveProfiles("test"), spring.profiles.active=test, or a number of other ways. Classes can be excluded with #Profile("!test")
More details here: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-profiles
Also, by activating a profile, you may also activate a properties file to be picked up... You may also have files in your project like:
application.properties
application-default.properties
application-test.properties
If you have application.properties present as well as application-test.properties, application.properties forms the base config, and application-test.properties will overwrite any existing properties and may also supply additional configuration values.
If you supply/specify no profile, the default profile is activated. This will result in application.properties + application-default.properties being combined (as before).
You will see in the logs which profile is activated very near the beginning of the Spring log output.
Actually have a little problem.
I want switch the url of my bootstrap.yml
It looks as follows:
spring:
application:
name: <project-name>
profiles:
active: dev
cloud:
config:
uri: http://<git-repository>:8080
fail-fast: false
This works, but i want have an propertie or anything what can switch if are in local or another enviroment.
I try to see this documentation but dont see any work for me.
I don't think Spring Cloud is any different from any Spring application, so you could use the Spring profiles.
Something similar is suggested on this answer: https://stackoverflow.com/a/22759706/6908551.
You could define a separate .yml file just for your cloud config uri, like cloud-config-dev.yml, cloud-config-prod.yml. Then, for a Java config, you could have something like:
#Configuration
public class MyApplicationConfiguration {
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
String activeProfile = System.getProperty("spring.profiles.active", "production");
String ymlFilename = "cloud-config-" + activeProfile + ".yml";
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource(ymlFilename));
return configurer;
}
}
I would define a bootstrap.yml file by environment.
Define a default bootstrap.yml in src/main/resources and define a specific bootstrap.yml file for each environment.
Then there are multiple ways.
Not exhaustive :
1) For each environment where the configuration file differs, run your spring boot jar by specifying the system property spring.cloud.bootstrap.location with the expected value such as :
java -jar ... -Dspring.cloud.bootstrap.location=bootstrap-dev.yml ....
That overrides the current location of that file.
2) Take advantage of Spring Boot profile feature : bootstrap.yml is compatible with. For example if the dev profile is enabled, the bootstrap-dev.properties in the classpath will be used.
I tend to use the first way because that is more explicit for non Spring Boot users.
Source : 1.3 Changing the Location of Bootstrap Properties
My application outlines are growing. I am looking for some solution to store configurations for each circuit.
I think that such a configuration format would be nice :
someHost:
test: testUrl
local: localUrl
dev: devUrl
qa: qaUrl
stage: stageUrl
prod: prodUrl
So far, I don’t have an understanding of how to properly configure my application so that it works correctly with the necessary configurations depending on the profile. Do you have any solution?
Stack: Java, Spring Boot 2, Kubernetes
To keep format you propose you will need to create another variable where you will configure prefix.
hostPrefix: dev
someHost:
test: testUrl
local: localUrl
dev: devUrl
qa: qaUrl
stage: stageUrl
prod: prodUrl
Then inject it with #Value in required field with inner placeholders:
#Value("${someHost.${hostPrefix}}")
private String url;
Thats it. In current solution it will be resolved to ${someHost.dev}, which would be resolved to devUrl. You can also use spring profile for that:
#Value("${someHost.${spring.profiles}}")
private String url;
You can use Spring's profiles for that.
Define a profile per environment, and then it can have it's own set of properties and beans
Seems like you already have configuration in yml format. Then you can use spring profiles like this:
spring:
profiles:
active: dev
someHost:
url: devUrl
---
spring:
profiles: test
someHost:
url: testUrl
---
spring:
profiles: qa
someHost:
url: qaUrl
And then you create #Configuration:
#Configuration
#ConfigurationProperties("someHost")
public class SomeHostConfig {
private String url;
}
Or you can use any managed bean field and inject it with #Value:
#Value("${someHost.url}")
private String someHostUrl;
Then you run your application with profile. For example, in maven it would be:
mvn spring-boot:run -Dspring.profiles.active=dev
I'm new to Spring Boot so sorry if this is too basic. My code takes a lot of time to build. I figured out that it's because Spring is loading a lot of config files that are not really needed.
My main file :
#EnableSwagger2
#SpringBootApplication
#IntegrationComponentScan
#EnableIntegration
public class MySystem {
public static void main(String[] args) {
run(MySystem.class, args);
}
}
I tried using #EnableAutoConfiguration(exclude = {classes to exclude}) but the unused classes imported by Spring boot on build time are too much to include here individually, there are hundreds of them. Is there a way to exclude unused config files in batch or in group? Or maybe I'm doing something wrong?
I have the following spring-boot 1.4.2.RELEASE sample app
#SpringBootApplication
public class Application {
#Value("${spring.application.name}")
private String applicationName;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
And I have the following configuration defined in bootstrap.properties:
spring.application.name=sample-app
When run it I get the following error:
java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.application.name' in string value "${spring.application.name}"
Any hint on why it fails to inject 'spring.application.name'?
Need to define it there to support other spring boot cloud.
The first answer is correct. The default properties file is application.properties or application.yml.
The bootstrap file is properly for Spring Cloud.
See http://projects.spring.io/spring-cloud/spring-cloud.html#_the_bootstrap_application_context
If you are using spring cloud, and the bootstrap file is not working, you need to enable the "cloud" Spring profile.
For example using:
./gradlew -Dspring.profiles.active=cloud bootrun
or
./mvnw spring-boot:run -Dspring.profiles.active=cloud
By default, if you don't specify any properties source, spring boot will lookup for your property in the file application.properties. Therefore, you should rename your property file to that default name or manually specify a properties source for your bootstrap.properties