【问题标题】:Can a PropertiesFactoryBean read a value from application.yml?PropertiesFactoryBean 可以从 application.yml 中读取值吗?
【发布时间】:2014-02-27 07:29:31
【问题描述】:

我的项目有一个依赖项,需要设置一个可以被@Value 注解读取的属性对象:

@Value("#{myProps['property.1']}")

要在 JavaConfig 中执行此操作,我使用以下内容:

@Bean(name="myProps")
public static PropertiesFactoryBean mapper() {
    PropertiesFactoryBean bean = new PropertiesFactoryBean();
    bean.setLocation(new ClassPathResource("myprops.properties"));
    return bean;
}

这按预期工作。我的属性如下所示:

property.1=http://localhost/foo/bar
property.2=http://localhost/bar/baz
property.3=http://localhost/foo/baz

我正在为这个项目使用 Spring Boot,所以我希望能够执行以下操作:

myprops.properties:
    property.1=${base.url}/foo/bar
    property.2=${base.url}/bar/baz
    property.3=${base.url}/foo/baz

然后我可以根据不同的配置文件配置base.url。

application.yml:

    base:
      url: http://localhost

    ---
    spring:
      profiles: staging
    base:
      url: http://staging

    ---
    spring:
      profiles: production
    base:
      url: http://production

我已经尝试过这样做,但它不起作用。作为一种解决方法,我创建了三个不同的 .properties 文件(myprops.properties、myprops-staging.properties 等)并使用三个不同的 @Configuration 类加载它们。这可行,但看起来很麻烦。

@Configuration
public class DefaultConfiguration {

    @Bean(name="myProps")
    public static PropertiesFactoryBean mapper() {
        PropertiesFactoryBean bean = new PropertiesFactoryBean();
        bean.setLocation(new ClassPathResource("myprops.properties"));
        return bean;
    }
}

@Configuration
@Profile("staging")
public class StagingConfiguration {

    @Bean(name="myProps")
    public static PropertiesFactoryBean mapper() {
        PropertiesFactoryBean bean = new PropertiesFactoryBean();
        bean.setLocation(new ClassPathResource("myprops-staging.properties"));
        return bean;
    }
}

@Configuration
@Profile("production")
public class ProductionConfiguration {

    @Bean(name="myProps")
    public static PropertiesFactoryBean mapper() {
        PropertiesFactoryBean bean = new PropertiesFactoryBean();
        bean.setLocation(new ClassPathResource("myprops-production.properties"));
        return bean;
    }
}

是否可以将我的 PropertiesFactoryBean 配置为从 application.yml 读取值?如果没有,是否有更简单的方法来使用 JavaConfig 配置属性?

【问题讨论】:

    标签: spring spring-boot spring-java-config


    【解决方案1】:

    我最终以编程方式执行此操作,它为我提供了我正在寻找的行为:

    @Value("${base.url}")
    private String baseUrl;
    
    @Bean(name = "myProps")
    public PropertiesFactoryBean mapper() throws IOException {
        PropertiesFactoryBean bean = new PropertiesFactoryBean();
        bean.setLocation(new ClassPathResource("myprops.properties"));
        bean.afterPropertiesSet();
    
        // replace ${base.url} in values
        Properties props = bean.getObject();
        Enumeration names = props.propertyNames();
    
        while (names.hasMoreElements()) {
            String name = names.nextElement().toString();
            String value = props.getProperty(name);
            if (value.contains("${base.url}")) {
                props.setProperty(name, value.replace("${base.url}", baseUrl));
            }
        }
    
        bean.setLocalOverride(true);
        bean.setProperties(props);
        bean.afterPropertiesSet();
    
        if (log.isDebugEnabled()) {
            log.debug("Base URL: " + baseUrl);
        }
    
        return bean;
    }
    

    【讨论】:

      【解决方案2】:

      我不能 100% 确定你真正想要在那里做什么,你也没有说什么不起作用,但看起来你想为你的外部配置混合 YAML 和属性格式?为什么不直接使用“application.yml”?如果我正在做类似的事情,并且出于某种原因我需要使用属性文件,那么我会在我的SpringApplication 源文件之一上使用@PropertySource(这样占位符我认为应该在解决值时替换)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 2018-07-28
        • 1970-01-01
        • 2022-11-14
        • 1970-01-01
        相关资源
        最近更新 更多