使用 YAML 的 Spring @PropertySource
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21271468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @PropertySource using YAML
提问by checketts
Spring Boot allows us to replace our application.properties files with YAML equivalents. However I seem to hit a snag with my tests. If I annotate my TestConfiguration
(a simple Java config), it is expecting a properties file.
Spring Boot 允许我们用 YAML 等效文件替换我们的 application.properties 文件。但是,我的测试似乎遇到了障碍。如果我注释我的TestConfiguration
(一个简单的 Java 配置),它需要一个属性文件。
For example this doesn't work:
@PropertySource(value = "classpath:application-test.yml")
例如,这不起作用:
@PropertySource(value = "classpath:application-test.yml")
If I have this in my YAML file:
如果我的 YAML 文件中有这个:
db:
url: jdbc:oracle:thin:@pathToMyDb
username: someUser
password: fakePassword
And I'd be leveraging those values with something like this:
我会用这样的东西来利用这些价值:
@Value("${db.username}") String username
However, I end up with and error like so:
但是,我最终得到了这样的错误:
Could not resolve placeholder 'db.username' in string value "${db.username}"
How can I leverage the YAML goodness in my tests as well?
我怎样才能在我的测试中利用 YAML 的优点?
采纳答案by Ola Sundell
Spring-boot has a helper for this, just add
Spring-boot 有一个帮手,只需添加
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
at the top of your test classes or an abstract test superclass.
在您的测试类或抽象测试超类的顶部。
Edit: I wrote this answer five years ago. It doesn't work with recent versions of Spring Boot. This is what I do now (please translate the Kotlin to Java if necessary):
编辑:我五年前写了这个答案。它不适用于最新版本的 Spring Boot。这就是我现在所做的(如有必要,请将 Kotlin 翻译成 Java):
@TestPropertySource(locations=["classpath:application.yml"])
@ContextConfiguration(
initializers=[ConfigFileApplicationContextInitializer::class]
)
is added to the top, then
添加到顶部,然后
@Configuration
open class TestConfig {
@Bean
open fun propertiesResolver(): PropertySourcesPlaceholderConfigurer {
return PropertySourcesPlaceholderConfigurer()
}
}
to the context.
到上下文。
回答by Mateusz Balbus
As it was mentioned @PropertySource
doesn't load yaml file. As a workaround load the file on your own and add loaded properties to Environment
.
如前所述,它@PropertySource
不会加载 yaml 文件。作为一种解决方法,您可以自行加载文件并将加载的属性添加到Environment
.
Implemement ApplicationContextInitializer
:
实施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);
}
}
}
Add your initializer to your test:
将您的初始化程序添加到您的测试中:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class, initializers = YamlFileApplicationContextInitializer.class)
public class SimpleTest {
@Test
public test(){
// test your properties
}
}
回答by Сергей Варюхин
@PropertySource
can be configured by factory
argument. So you can do something like:
@PropertySource
可以通过factory
参数配置。因此,您可以执行以下操作:
@PropertySource(value = "classpath:application-test.yml", factory = YamlPropertyLoaderFactory.class)
Where YamlPropertyLoaderFactory
is your custom property loader:
YamlPropertyLoaderFactory
您的自定义属性加载器在哪里:
public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null){
return super.createPropertySource(name, resource);
}
return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), null);
}
}
Inspired by https://stackoverflow.com/a/45882447/4527110
回答by Dave Syer
回答by moogpwns
From Spring Boot 1.4, you can use the new @SpringBootTest
annotation to achieve this more easily (and to simplify your integration test setup in general) by bootstrapping your integration tests using Spring Boot support.
从 Spring Boot 1.4 开始,您可以使用新的@SpringBootTest
注解通过使用 Spring Boot 支持引导集成测试来更轻松地实现这一点(并简化您的集成测试设置)。
Details on the Spring Blog.
Spring 博客上的详细信息。
As far as I can tell, this means you get all the benefits of Spring Boot's externalized config goodnessjust like in your production code, including automatically picking up YAML config from the classpath.
据我所知,这意味着您可以像在生产代码中一样获得 Spring Boot 的外部化配置优点的所有好处,包括从类路径中自动获取 YAML 配置。
By default, this annotation will
默认情况下,此注释将
... first attempt to load
@Configuration
from any inner-classes, and if that fails, it will search for your primary@SpringBootApplication
class.
...首先尝试
@Configuration
从任何内部类加载,如果失败,它将搜索您的主要@SpringBootApplication
类。
but you can specify other configuration classes if required.
但如果需要,您可以指定其他配置类。
For this particular case, you can combine @SpringBootTest
with @ActiveProfiles( "test" )
and Spring will pick up your YAML config, provided it follows the normal Boot naming standards (i.e. application-test.yml
).
对于这种特殊情况,如果它遵循正常的引导命名标准(即),您可以结合@SpringBootTest
使用@ActiveProfiles( "test" )
并且 Spring 将选择您的 YAML 配置application-test.yml
。
@RunWith( SpringRunner.class )
@SpringBootTest
@ActiveProfiles( "test" )
public class SpringBootITest {
@Value("${db.username}")
private String username;
@Autowired
private MyBean myBean;
...
}
Note: SpringRunner.class
is the new name for SpringJUnit4ClassRunner.class
注意:SpringRunner.class
是新名称SpringJUnit4ClassRunner.class
回答by Doc Davluz
Another option is to set the spring.config.location
through @TestPropertySource
:
另一种选择是设置spring.config.location
through @TestPropertySource
:
@TestPropertySource(properties = { "spring.config.location = classpath:<path-to-your-yml-file>" }
回答by Biju Kunjummen
The approach to loading the yaml properties, IMHO can be done in two ways:
加载 yaml 属性的方法,恕我直言,可以通过两种方式完成:
a. You can put the configuration in a standard location - application.yml
in the classpath root - typically src/main/resources
and this yaml property should automatically get loaded by Spring boot with the flattened path name that you have mentioned.
一种。您可以将配置放在标准位置 -application.yml
在类路径根目录中 - 通常src/main/resources
,这个 yaml 属性应该由 Spring boot 使用您提到的扁平路径名自动加载。
b. The second approach is a little more extensive, basically define a class to hold your properties this way:
湾 第二种方法更广泛一些,基本上定义一个类来以这种方式保存您的属性:
@ConfigurationProperties(path="classpath:/appprops.yml", name="db")
public class DbProperties {
private String url;
private String username;
private String password;
...
}
So essentially this is saying that load the yaml file and populate the DbProperties class based on the root element of "db".
所以基本上这就是说加载 yaml 文件并根据“db”的根元素填充 DbProperties 类。
Now to use it in any class you will have to do this:
现在要在任何课程中使用它,您必须这样做:
@EnableConfigurationProperties(DbProperties.class)
public class PropertiesUsingService {
@Autowired private DbProperties dbProperties;
}
Either of these approaches should work for you cleanly using Spring-boot.
这些方法中的任何一种都应该使用 Spring-boot 干净地为您工作。
回答by Poly
I found a workaround by using @ActiveProfiles("test")
and adding an application-test.yml file to src/test/resources.
我通过使用@ActiveProfiles("test")
并将 application-test.yml 文件添加到 src/test/resources找到了一种解决方法。
It ended up looking like this:
它最终看起来像这样:
@SpringApplicationConfiguration(classes = Application.class, initializers = ConfigFileApplicationContextInitializer.class)
@ActiveProfiles("test")
public abstract class AbstractIntegrationTest extends AbstractTransactionalJUnit4SpringContextTests {
}
The file application-test.yml just contains the properties that I want to override from application.yml (which can be found in src/main/resources).
文件 application-test.yml 只包含我想从 application.yml 覆盖的属性(可以在 src/main/resources 中找到)。
回答by user2582794
it's because you have not configure snakeyml. spring boot come with @EnableAutoConfiguration feature. there is snakeyml config too when u call this annotation..
那是因为你没有配置snakeyml。spring boot 带有@EnableAutoConfiguration 功能。当你调用这个注释时,也有snakeyml配置..
this is my way:
这是我的方式:
@Configuration
@EnableAutoConfiguration
public class AppContextTest {
}
here is my test:
这是我的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(
classes = {
AppContextTest.class,
JaxbConfiguration.class,
}
)
public class JaxbTest {
//tests are ommited
}
回答by U.V.
I needed to read some properties into my code and this works with spring-boot 1.3.0.RELEASE
我需要将一些属性读入我的代码中,这适用于 spring-boot 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);
}