【问题标题】:Setting up Spring 4.1 profile environment using YAML instead of Properties and @Profile使用 YAML 而不是 Properties 和 @Profile 设置 Spring 4.1 配置文件环境
【发布时间】:2015-09-30 08:36:23
【问题描述】:

我正在尝试使用 YAML 配置文件设置我的配置文件。我不想让不同的@Configuration 类用@Profile 注释不同的类(或者甚至相同的@Configuration 类具有不同的注释@Beans),我希望有一个@Configuration 类使用带有YAML 配置文件的占位符。

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

一个简单的 YAML 文件: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));

  }
}

我注意到在我的测试类中,我可以通过@Value 注释访问“foo”属性,但不能通过Environment。 正如 thisthat 等一些 Stackoverflow 主题中所解释的那样,将 PropertySourcesPlaceholderConfigurer 注释为 @Bean 并不足以将其与 Environment 紧密结合。有必要像我在Application 类中那样以编程方式进行。相比之下,带注释的@Values 会相应地连线。

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

有什么理由我应该更喜欢使用@Value(或任何其他配置文件配置)而不是Environment + YAML 配置文件?正如我所说,我希望有一个独特的@Bean 使用占位符而不是使用@Profiles 注释的多个@Beans。

【问题讨论】:

    标签: java spring


    【解决方案1】:

    我发现了这个SPR,其中 Chris Beams 说明了为什么 Spring 不应该自动注册 PropertySourcesPlaceholderConfigurer 以及为什么应该更喜欢用户 Environment 而不是 @value

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      相关资源
      最近更新 更多