使用YAML的Spring @PropertySource

Spring Boot允许我们用YAML等价物replace我们的application.properties文件。 但是,我似乎打破了我的testing的障碍。 如果我注释我的TestConfiguration (一个简单的Javaconfiguration),它期望一个属性文件。

例如,这是行不通的: @PropertySource(value = "classpath:application-test.yml")

如果我在我的YAML文件中有这个:

 db: url: jdbc:oracle:thin:@pathToMyDb username: someUser password: fakePassword 

我会用这样的东西来利用这些价值:

 @Value("${db.username}") String username 

但是,我最终会遇到这样的错误:

 Could not resolve placeholder 'db.username' in string value "${db.username}" 

我如何在testing中利用YAML的优点?

春季启动有一个帮手,只需添加

 @ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

在您的testing类或抽象testing超类的顶部。

@PropertySource只支持属性文件(这是Spring的一个限制,而不是引导本身)。 随意在JIRA中打开function请求票。

正如提到的@PropertySource不加载yaml文件。 作为解决方法,您可以自行加载文件,并将加载的属性添加到Environment

实现ApplicationContextInitializer

 public class YamlFileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { try { Resource resource = applicationContext.getResource("classpath:file.yml"); YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader(); PropertySource<?> yamlTestProperties = sourceLoader.load("yamlTestProperties", resource, null); applicationContext.getEnvironment().getPropertySources().addFirst(yamlTestProperties); } catch (IOException e) { throw new RuntimeException(e); } } } 

添加您的初始化程序到您的testing:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class, initializers = YamlFileApplicationContextInitializer.class) public class SimpleTest { @Test public test(){ // test your properties } } 

加载yaml属性的方法,恕我直言可以通过两种方式完成:

一个。 你可以把configuration放在classpath根目录下的标准位置application.yml中 – 通常是src/main/resources并且这个yaml属性应该在Spring引导时自动加载你所提到的扁平path名。

湾 第二种方法是更广泛一点,基本上定义一个类来保持你的属性这样:

 @ConfigurationProperties(path="classpath:/appprops.yml", name="db") public class DbProperties { private String url; private String username; private String password; ... } 

所以基本上这是说,加载yaml文件,并基于“db”的根元素填充DbProperties类。

现在要在任何课堂上使用它,你将不得不这样做:

 @EnableConfigurationProperties(DbProperties.class) public class PropertiesUsingService { @Autowired private DbProperties dbProperties; } 

这些方法中的任何一种都可以为你干净地使用Spring引导。

从Spring Boot 1.4开始,您可以使用新的@SpringBootTest批注,通过使用Spring Boot支持来引导您的集成testing,从而更轻松地实现此目的(并简化您的集成testing设置)。

有关Spring博客的详细信息。

据我所知,这意味着您可以像在生产代码中一样获得Spring Boot的外部configuration良好性的所有好处,包括从类path自动获取YAMLconfiguration。

默认情况下,这个注释将会

…首先尝试从任何内部类加载@Configuration ,如果失败,它将search您的主要@SpringBootApplication类。

但如果需要,您可以指定其他configuration类。

对于这个特殊的情况,你可以将@SpringBootTest@ActiveProfiles( "test" )结合起来,如果它遵循正常的Boot命名标准(例如application-test.yml ),Spring会select你的YAMLconfiguration。

 @RunWith( SpringRunner.class ) @SpringBootTest @ActiveProfiles( "test" ) public class SpringBootITest { @Value("${db.username}") private String username; @Autowired private MyBean myBean; ... } 

注意: SpringRunner.classSpringRunner.class的新名称

我通过使用@ActiveProfiles("test")并添加一个application-test.yml文件到src / test / resources来find解决方法。

它最终看起来像这样:

 @SpringApplicationConfiguration(classes = Application.class, initializers = ConfigFileApplicationContextInitializer.class) @ActiveProfiles("test") public abstract class AbstractIntegrationTest extends AbstractTransactionalJUnit4SpringContextTests { } 

文件application-test.yml只包含我想从application.yml(可以在src / main / resources中find)重写的属性。

另一个选项是通过@TestPropertySource设置@TestPropertySource

 @TestPropertySource(properties = { "spring.config.location = classpath:<path-to-your-yml-file>" } 

我需要阅读一些属性到我的代码,这与春季启动1.3.0.RELEASE

 @Autowired private ConfigurableListableBeanFactory beanFactory; // access a properties.yml file like properties @Bean public PropertySource properties() { PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); yaml.setResources(new ClassPathResource("properties.yml")); propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject()); // properties need to be processed by beanfactory to be accessible after propertySourcesPlaceholderConfigurer.postProcessBeanFactory(beanFactory); return propertySourcesPlaceholderConfigurer.getAppliedPropertySources().get(PropertySourcesPlaceholderConfigurer.LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME); } 

在testing单元中@value对于来自属性文件的调用属性有一些问题,所以你可以使用环境来replace值

 @Autowired private Environment environment; public void init(){ String username=environment.getRequiredProperty("db.username"); } 

所以你现在可以在生产和testing部门打电话给财产

这是因为你没有configurationsnakeyml。 春季开机来了@EnableAutoConfigurationfunction。 当你调用这个注解的时候也有snakeymlconfiguration。

这是我的方式:

 @Configuration @EnableAutoConfiguration public class AppContextTest { } 

这是我的testing:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration( classes = { AppContextTest.class, JaxbConfiguration.class, } ) public class JaxbTest { //tests are ommited } 

在Spring Boot中加载具有多个configuration文件configuration的自定义yml文件。

1)添加SpringBootApplication属性bean启动,如下所示

 @SpringBootApplication @ComponentScan({"com.example.as.*"}) public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @Bean @Profile("dev") public PropertySourcesPlaceholderConfigurer propertiesStage() { return properties("dev"); } @Bean @Profile("stage") public PropertySourcesPlaceholderConfigurer propertiesDev() { return properties("stage"); } @Bean @Profile("default") public PropertySourcesPlaceholderConfigurer propertiesDefault() { return properties("default"); } /** * Update custom specific yml file with profile configuration. * @param profile * @return */ public static PropertySourcesPlaceholderConfigurer properties(String profile) { PropertySourcesPlaceholderConfigurer propertyConfig = null; YamlPropertiesFactoryBean yaml = null; propertyConfig = new PropertySourcesPlaceholderConfigurer(); yaml = new YamlPropertiesFactoryBean(); yaml.setDocumentMatchers(new SpringProfileDocumentMatcher(profile));// load profile filter. yaml.setResources(new ClassPathResource("env_config/test-service-config.yml")); propertyConfig.setProperties(yaml.getObject()); return propertyConfig; } } 

2)configurationJava POJO对象如下

 @Component @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) @ConfigurationProperties(prefix = "test-service") public class TestConfig { @JsonProperty("id") private String id; @JsonProperty("name") private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 

3)创build自定义yml(并将其放置在资源path下,如下所示,YML文件名:test-service-config.yml

例如在yml文件中configuration。

 test-service: id: default_id name: Default application config --- spring: profiles: dev test-service: id: dev_id name: dev application config --- spring: profiles: stage test-service: id: stage_id name: stage application config