在 Spring Boot 中使用 @PropertySource 加载 YAML 文件

更新于 2025-12-30

Krzysztof Woyke 2020-05-20

1. 概述

在本篇快速教程中,我们将展示如何在 Spring Boot 中使用 @PropertySource 注解读取 YAML 格式的配置文件。

2. @PropertySource 与 YAML 格式

Spring Boot 对外部化配置提供了出色的支持。此外,Spring Boot 开箱即用地支持多种方式和格式来读取应用程序中的属性配置。

然而,默认情况下,@PropertySource 并不支持加载 YAML 文件。这一点在官方文档中有明确说明。

因此,如果我们希望在应用中使用 @PropertySource 注解,通常只能使用标准的 .properties 文件。当然,我们也可以自己实现缺失的这一部分功能!

3. 自定义 PropertySourceFactory

从 Spring 4.3 开始,@PropertySource 注解新增了 factory 属性。我们可以利用该属性提供自定义的 PropertySourceFactory 实现,以处理 YAML 文件的解析。

实现起来其实比想象中简单!让我们看看具体做法:

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) 
      throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(encodedResource.getResource());

        Properties properties = factory.getObject();

        return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
    }
}

如上所示,我们只需实现 createPropertySource 方法即可。

在自定义实现中,首先使用 YamlPropertiesFactoryBean 将 YAML 格式的资源转换为 java.util.Properties 对象。
然后,我们返回一个新的 PropertiesPropertySource 实例——它是一个包装器,使 Spring 能够读取已解析的属性。

4. @PropertySource 与 YAML 的实际应用

现在,让我们整合所有组件,并演示如何在实践中使用它们。

首先,创建一个简单的 YAML 文件 —— foo.yml

yaml:
  name: foo
  aliases:
    - abc
    - xyz

接下来,创建一个使用 @ConfigurationProperties 的配置类,并指定我们自定义的 YamlPropertySourceFactory

@Configuration
@ConfigurationProperties(prefix = "yaml")
@PropertySource(value = "classpath:foo.yml", factory = YamlPropertySourceFactory.class)
public class YamlFooProperties {

    private String name;

    private List<String> aliases;

    // 标准的 getter 和 setter 方法
}

最后,验证属性是否被正确注入:

@RunWith(SpringRunner.class)
@SpringBootTest
public class YamlFooPropertiesIntegrationTest {

    @Autowired
    private YamlFooProperties yamlFooProperties;

    @Test
    public void whenFactoryProvidedThenYamlPropertiesInjected() {
        assertThat(yamlFooProperties.getName()).isEqualTo("foo");
        assertThat(yamlFooProperties.getAliases()).containsExactly("abc", "xyz");
    }
}

5. 结论

总结一下,在本篇快速教程中,我们首先展示了如何轻松创建一个自定义的 PropertySourceFactory。随后,我们演示了如何通过 @PropertySource 注解的 factory 属性传入该自定义实现。

最终,我们成功地将 YAML 配置文件加载到了 Spring Boot 应用程序中。