java - Spring Boot 使用 ConfigurationProperties 从 .properties 和 .yaml 注入(inject)映射值

标签 java spring spring-boot

当我尝试从 .properties 文件与 .yaml 文件注入(inject) Map 时,我注意到 Spring 中的行为存在差异文件。我正在使用 Spring 的 ConfigurationProperties 来执行此操作。

文件:

products.yaml:

test-service:
  products:
    1: alpha
    2: bravo
    3: charlie

产品.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 文件(失败)。

为什么?

最佳答案

您的代码中有两个问题

TestPropertySource无法使用 PropertySourceTestPropertySource 注释加载 YAML 文件

@TestPropertySource is a class-level annotation that is used to configure the locations() of properties files and inlined properties() to be added to the Environment's set of PropertySources for an ApplicationContext for integration tests.

YAML Shortcomings

YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.

因此,将您的 yml 文件名更改为 application.yml,然后您仍然需要在测试类上添加 @SpringBootTest 注释来绑定(bind)这些yml 文件中的属性

Loading YAML Spring Boot有binder utils

To bind to properties like that by using Spring Boot’s Binder utilities (which is what @ConfigurationProperties does), you need to have a property in the target bean of type java.util.List (or Set) and you either need to provide a setter or initialize it with a mutable value.

@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环境中

关于java - Spring Boot 使用 ConfigurationProperties 从 .properties 和 .yaml 注入(inject)映射值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57422752/

相关文章:

Java图形,什么也没有显示

spring - 集成测试用例及文件上传

java - 项目重建后 Hibernate H2 数据库锁定

java - 当有多个用户同时访问页面时,是否需要在我的controller方法中添加synchronization关键字?

java - 在 spring bean 中访问 Db 时的线程安全

java - Android:如何将可绘制资源附加到电子邮件?

java - Android Studio 按钮没有响应(OnClick)

java - 创建多模块maven项目时出错

java - 尝试在 Spring Boot/Spring Security Web 应用程序中打开 .css 文件时,为什么会收到 "405 - Method Not Allowed"错误?

spring-boot - 关于 spring.http.multipart.max-file-size 与 spring.servlet.multipart.max-file-size 的混淆