java - Spring Boot 使用 ConfigurationProperties 从 .properties 和 .yaml 注入 Map 值
问题描述
当我尝试Map
从.properties
文件和.yaml
文件注入 a 时,我注意到 Spring 中的行为有所不同。我正在使用 SpringConfigurationProperties
来执行此操作。
文件:
products.yaml
:
test-service:
products:
1: alpha
2: bravo
3: charlie
products.properties
:
test-service.products.1=alpha
test-service.products.2=bravo
test-service.products.3=charlie
我ProductProperties
加载属性的类:
@ConfigurationProperties("test-service")
public class ProductProperties {
private final Map<String, String> products = new HashMap<>();
public Map<String, String> getProducts() {
return products;
}
}
单元测试ProductPropertiesPropertiesTest
,通过:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ProductProperties.class)
@TestPropertySource("classpath:products.properties")
@EnableConfigurationProperties(ProductProperties.class)
public class ProductPropertiesPropertiesTest {
@Autowired
private ProductProperties productProperties;
@Test
public void testProperties() {
assertEquals(3, productProperties.getProducts().size()); // passes
}
}
单元测试ProductPropertiesYamlTest
,失败:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ProductProperties.class)
@TestPropertySource("classpath:products.yaml")
@EnableConfigurationProperties(ProductProperties.class)
public class ProductPropertiesYamlTest {
@Autowired
private ProductProperties productProperties;
@Test
public void testProperties() {
assertEquals(3, productProperties.getProducts().size()); // fails
}
}
两个测试之间的唯一区别是属性的来源:一个.properties
文件(通过)和一个.yaml
失败的文件。
为什么?
解决方案
你的代码有两个问题
YAML
无法使用PropertySource
和TestPropertySource
注释加载TestPropertySource文件
@TestPropertySource 是一个类级别的注释,用于配置属性文件的位置()和内联属性(),以添加到环境的一组属性源中,用于集成测试的 ApplicationContext。
无法使用 @PropertySource 注解加载 YAML 文件。因此,如果您需要以这种方式加载值,则需要使用属性文件。
因此,将您的yml
文件名更改为application.yml
,然后您仍然需要@SpringBootTest
在测试类上添加注释以从 yml 文件中绑定这些属性
加载 YAML Spring boot 有 binder utils
要通过使用 Spring Boot 的 Binder 实用程序(这是 @ConfigurationProperties 所做的)绑定到类似的属性,您需要在目标 bean 类型为 java.util.List(或 Set)中具有一个属性,并且您需要提供一个 setter或使用可变值对其进行初始化。
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ProductProperties.class)
//default to application.yml
@EnableConfigurationProperties(ProductProperties.class)
@SpringBootTest
public class ProductPropertiesPropertiesTest {
@Autowired
private ProductProperties productProperties;
@Test
public void testProperties() {
assertEquals(3, productProperties.getProducts().size()); // passes
}
}
但是对于属性文件@SpringBootTest
是可选的,因为默认情况下 SpringApplication 从 application.properties 文件加载属性并将它们添加到 Spring Environment
推荐阅读
- php - 如何在 Woocommerce 中以编程方式创建 woocommerce 订单?
- java - 当用户按“回车”键或空格回车时,会弹出错误消息
- dictionary - Flutter:将两个列表映射在一起
- javascript - CryptoJS 和 Python Hashlib 的等效 MD5
- php - (PHP) var_dumping 结构化格式的对象。
- encryption - 使用非对称 RSA 密钥包装对称密钥
- javascript - Webpack(VueJS) 为 FIrefox 和 Chrome 制作不同的图像路径
- java - 使用方法更改变量,然后无法将值分配给另一个变量
- javascript - Javascript - 有没有办法从函数调用参数中获取字符串?
- javascript - 静态函数不是函数javascript