问题
I have a single application.yml
configuration file for my Spring Boot app that defines two profiles (as described in the documentation).
When the production profile is enabled, I would like to set the http.maxConnections system property to a custom value, e.g.
spring:
profiles:
active: dev
---
spring:
profiles: dev
---
spring:
profiles: production
http:
maxConnections: 15
But this doesn't actually set the system level property; it appears to just create an application-level property. I've verified this through both http://locahost:8080/env and a JMX Console when comparing launching by
java -jar -Dspring.profiles.active=production myapp.jar
versus
java -Dhttp.maxConnections=15 myapp.jar
I suppose I could create a bean that's @Conditional
on the "production" profile that programmatically callsSystem.setProperty
based on my application.yml
-defined property, but is there a simpler way through configuration files alone?
回答1:
I suppose I could create a bean that's @Conditional on the "production" profile that programmatically callsSystem.setProperty based on my application.yml-defined property, but is there a simpler way through configuration files alone?
I think that's your best bet here. Spring Boot does that itself in its LoggingSystem
where various logging.*
properties are mapped to System properties.
Note that you'll probably want to set the system properties as early as possible, probably as soon as the Environment
is prepared. To do so, you can use an ApplicationListener
that listens for the ApplicationEnvironmentPreparedEvent
. Your ApplicationListener
implementation should be registered via an entry in spring.factories
.
回答2:
You may try.
@Profile("production")
@Component
public class ProductionPropertySetter {
@PostConstruct
public void setProperty() {
System.setProperty("http.maxConnections", 15);
}
}
回答3:
You can inject the environment into the constructor of the class that specifies the beans. This allows you to write application properties to the system properties before the beans are being created.
@Configuration
public class ApplicationBeans {
@Autowired
public ApplicationBeans(Environment environment) {
// set system properties before the beans are being created.
String property = "com.application.property";
System.getProperties().setProperty(property, environment.getProperty(property));
}
/**
* Bean that depends on the system properties
*/
@Bean
public SomeBean someBean() {
return new SomeBean();
}
}
回答4:
You can also use PropertyPlaceholderConfigurer from org.springframework.beans.factory.config to get handle over your properties file
回答5:
@PostConstruct
the initialization happens in this order:
First, the container calls the bean constructor (the default constructor or the one annotated @Inject), to obtain an instance of the bean.
Next, the container initializes the values of all injected fields of the bean.
Next, the container calls all initializer methods of bean (the call order is not portable, don’t rely on it).
Finally, the @PostConstruct method, if any, is called.
So, the purpose of using @PostConstruct is clear; it gives you a chance to initialize injected beans, resources etc.
public class Person {
// you may have injected beans, resources etc.
public Person() {
System.out.println("Constructor is called...");
}
@PostConstruct
public void init() {
System.out.println("@PostConstruct is called...");
} }
So, the output by injecting a Person bean will be;
Constructor is called...
@PostConstruct is called...
来源:https://stackoverflow.com/questions/36895711/can-i-define-system-properties-within-spring-boot-configuration-files