Java 使用YAML而不是属性和@profile设置Spring4.1概要文件环境

Java 使用YAML而不是属性和@profile设置Spring4.1概要文件环境,java,spring,Java,Spring,我正在尝试使用YAML配置文件设置我的配置文件。对于不同的@Configuration类(甚至是同一个@Configuration类,具有不同的@Beans),我希望有一个@Configuration类使用带有YAML配置文件的占位符 看一下,我得到了以下代码: 一个简单的YAML文件:applicationdefaultconfig.yml foo: myFoo @配置文件: import org.springframework.beans.factory.annotation.Value;

我正在尝试使用YAML配置文件设置我的配置文件。对于不同的
@Configuration
类(甚至是同一个
@Configuration
类,具有不同的
@Beans
),我希望有一个
@Configuration
类使用带有YAML配置文件的占位符

看一下,我得到了以下代码:

一个简单的YAML文件:
applicationdefaultconfig.yml

foo: myFoo
@配置
文件:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;

@Configuration
public class ApplicationConfig {

  @Bean
  public static PropertySourcesPlaceholderConfigurer ymlProperties() {
    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer =
        new PropertySourcesPlaceholderConfigurer();

    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    yaml.setResources(new ClassPathResource("config/application-${spring.profiles.active:default}-config.yml"));
        propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());

    return propertySourcesPlaceholderConfigurer;
  }

  @Value("${foo}")
  private String fooValue;

  @Bean
  public String fooValue() {
    return fooValue;
  }
}
测试文件:

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ApplicationConfig.class)
public class ApplicationConfigTest {    

  @Autowired
  Environment environment;

  @Autowired
  String fooValue;

  @Test
  public void testFooViaEnvironment() {
    Assert.assertEquals("myFoo", environment.getProperty("foo"));
  }

  @Test
  public void testFooViaWiredValue() {
    Assert.assertEquals("myFoo", fooValue);
  }
}
最后是一个主文件:

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ClassPathResource;

public class Application {
  public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

    ctx.register(ApplicationConfig.class);

    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    yaml.setResources(new ClassPathResource("config/application-${spring.profiles.active:default}-config.yml"));

    ConfigurableEnvironment environment = ctx.getEnvironment();
    environment.getPropertySources()
        .addFirst(new PropertiesPropertySource("custom", yaml.getObject()));

    ctx.refresh();

    String fooViaWiredValue = (String) ctx.getBean("fooValue");

    System.out.println(String.format("fooViaEnvironment=%s", environment.getProperty("foo")));

    System.out.println(String.format("fooViaWiredValue=%s", fooViaWiredValue));

  }
}
我注意到,在我的测试类中,我可以通过
@Value
注释访问'foo'属性,但不能通过
环境
访问。 正如在一些Stackoverflow主题(如和)中所解释的,将
属性资源占位符配置器
注释为
@Bean
不足以使其与
环境
紧密结合。有必要像我在
Application
类中所做的那样,以编程的方式完成它。相反,带注释的
@值
会相应地连接

事实上,我的问题是关于使用Spring的最佳实践。 我更喜欢使用
Environment
而不是
@Value
注释。 是否有任何方法可以将YAML配置文件加载到测试环境中的Spring应用程序上下文中,而无需像我在
应用程序
类中那样以编程方式进行加载

有什么理由我更喜欢使用
@Value
(或任何其他配置文件配置)而不是
环境
+YAML配置文件吗?正如我所说的,我想要一个使用占位符的独特的
@Bean
,而不是用
@Profile
s注释的多个
@Bean
s

我发现Chris Beams在这里说明了为什么PropertySourcesPlaceholderConfigurer不应该由Spring自动注册,以及为什么人们应该更喜欢用户
环境
而不是
@value

此外,在Spring参考文档中,显示了如何使用
ApplicationContextInitializer
,该初始化器可用于正确设置
YamlPropertiesFactoryBean