我可以在Spring Boot配置文件中定义系统属性吗?

时间:2016-04-27 16:31:00

标签: java spring-boot system-properties

我的Spring Boot应用程序有一个application.yml配置文件,用于定义两个配置文件(如documentation中所述)。

启用生产配置文件后,我想将http.maxConnections系统属性设置为自定义值,例如

spring:
    profiles:
        active: dev
---
spring:
    profiles: dev
---
spring:
    profiles: production
http:
    maxConnections: 15

但这并没有实际设置系统级属性;它似乎只是创建一个应用程序级属性。我在比较

启动时通过http://locahost:8080/env和JMX控制台验证了这一点
java -jar -Dspring.profiles.active=production myapp.jar

java -Dhttp.maxConnections=15 myapp.jar

我想我可以在"生产"上创建一个@Conditional的bean。根据我的System.setProperty定义的属性以编程方式调用application.yml的配置文件,但是仅通过配置文件有更简单的方法吗?

5 个答案:

答案 0 :(得分:8)

你可以试试。

@Profile("production")
@Component
public class ProductionPropertySetter {

   @PostConstruct
   public void setProperty() {
      System.setProperty("http.maxConnections", 15);
   }

}

答案 1 :(得分:4)

  

我想我可以在“生产”配置文件上创建一个@Conditional的bean,它根据我的application.yml-defined属性以编程方式调用System.setProperty,但是单独通过配置文件有一种更简单的方法吗?

我认为这是你最好的选择。 Spring Boot在其LoggingSystem中执行此操作,其中各种logging.*属性映射到系统属性。

请注意,您可能希望尽早设置系统属性,可能只要Environment准备就绪。为此,您可以使用侦听ApplicationListener的{​​{1}}。您的ApplicationEnvironmentPreparedEvent实施应通过ApplicationListener中的条目进行注册。

答案 2 :(得分:0)

您可以将环境注入指定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();
   }
}

答案 3 :(得分:0)

您还可以使用org.springframework.beans.factory.config中的PropertyPlaceholderConfigurer来处理属性文件

答案 4 :(得分:0)

@PostConstruct

初始化按以下顺序进行:

首先,容器调用Bean构造函数(默认构造函数或带注释的@Inject),以获取Bean的实例。

接下来,容器初始化bean的所有注入字段的值。

接下来,容器将调用bean的所有初始化方法(调用顺序不可移植,请不要依赖它)。

最后,调用@PostConstruct方法(如果有)。

因此,使用@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...");
    } }

因此,通过注入Person Bean的输出将为;

Constructor is called...

@PostConstruct is called...