Java 我可以在 Spring Boot 配置文件中定义系统属性吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36895711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I define System Properties within Spring Boot configuration files?
提问by bdkosher
I have a single application.yml
configuration file for my Spring Boot app that defines two profiles (as described in the documentation).
我的application.yml
Spring Boot 应用程序有一个配置文件,它定义了两个配置文件(如文档中所述)。
When the production profile is enabled, I would like to set the http.maxConnections
system property to a custom value, e.g.
启用生产配置文件后,我想将http.maxConnections
系统属性设置为自定义值,例如
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/envand a JMX Console when comparing launching by
但这实际上并没有设置系统级属性;它似乎只是创建了一个应用程序级属性。在比较启动时,我已经通过http://locahost:8080/env和 JMX 控制台验证了这一点
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?
我想我可以创建一个@Conditional
位于“生产”配置文件上的bean,该配置文件System.setProperty
基于我的application.yml
-defined 属性以编程方式调用,但是是否有更简单的方法来单独通过配置文件?
采纳答案by Andy Wilkinson
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?
我想我可以在“生产”配置文件上创建一个 @Conditional 的 bean,该配置文件根据我的 application.yml 定义的属性以编程方式调用 System.setProperty,但是是否有更简单的方法来单独通过配置文件?
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.
我认为这是你最好的选择。Spring Boot 在其LoggingSystem
将各种logging.*
属性映射到系统属性的地方自行完成。
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
.
请注意,您可能希望尽早设置系统属性,可能Environment
是在准备好后尽快设置。为此,您可以使用ApplicationListener
侦听ApplicationEnvironmentPreparedEvent
. 您的ApplicationListener
实现应该通过spring.factories
.
回答by TheKojuEffect
You may try.
你可以试试。
@Profile("production")
@Component
public class ProductionPropertySetter {
@PostConstruct
public void setProperty() {
System.setProperty("http.maxConnections", "15");
}
}
回答by jjoller
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.
您可以将环境注入到指定 bean 的类的构造函数中。这允许您在创建 bean 之前将应用程序属性写入系统属性。
@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();
}
}
回答by RamBharath
You can also use PropertyPlaceholderConfigurer from org.springframework.beans.factory.config to get handle over your properties file
您还可以使用 org.springframework.beans.factory.config 中的 PropertyPlaceholderConfigurer 来处理您的属性文件
回答by Mahdi Ben Selimene
@PostConstruct
@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.
首先,容器调用 bean 构造函数(默认构造函数或带有 @Inject 注释的构造函数),以获取 bean 的一个实例。
Next, the container initializes the values of all injected fields of the bean.
接下来,容器初始化 bean 的所有注入字段的值。
Next, the container calls all initializer methods of bean (the call order is not portable, don't rely on it).
接下来,容器调用bean的所有初始化方法(调用顺序不可移植,不要依赖)。
Finally, the @PostConstruct method, if any, is called.
最后,调用@PostConstruct 方法(如果有)。
So, the purpose of using @PostConstruct is clear; it gives you a chance to initialize injected beans, resources etc.
所以,使用@PostConstruct 的目的很明确;它让您有机会初始化注入的 bean、资源等。
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;
因此,注入 Person bean 的输出将是;
Constructor is called...
@PostConstruct is called...