使用YAML而不是Properties和@Profile设置Spring 4.1配置文件环境

时间:2015-07-11 18:20:06

标签: java spring

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

看一下Spring boot documentationYamlPropertiesFactoryBean javadocthis Stackoverflow topic,我想出了以下代码:

一个简单的YAML文件:@Configuration

application-default-config.yml

foo: myFoo 个文件:

@Configuration

测试文件:

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)); } } 注释访问'foo'属性,但不能通过@Value访问。 正如在thisthat等一些Stackoverflow主题中所解释的那样,将Environment注释为PropertySourcesPlaceholderConfigurer并不足以使用@Bean来限制它。有必要像我在Environment课程中那样以编程方式进行。相反,带注释的Application相应地连线。

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

我是否应该优先使用Application(或任何其他配置文件配置)而不是@Value + YAML配置文件?正如我所说,我希望使用占位符Environment,而不是使用@Bean s注释的倍数@Bean

1 个答案:

答案 0 :(得分:0)

我找到了这个SPR,其中Chris Beams说明为什么不应该由Spring自动注册PropertySourcesPlaceholderConfigurer,为什么人们应该更喜欢用户Environment而不是@value

此外,在Spring参考文档中,Spring Testing Annotation section显示了如何使用ApplicationContextInitializer,可用于正确设置YamlPropertiesFactoryBean