Springboot 从自定义 yaml 读取配置
@PropertySource注解
@PropertySource 注解是 Spring 3.1 开始引入的配置类注解。通过 @PropertySource 注解将 properties 配置文件中的值存储到 Spring 的 Environment中,Environment 接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。也可以使用@Value注解用${}占位符注入属性。
但是,默认情况下,@PropertySource 不会加载 yaml 文件,具体可查看官方文档 boot-features-external-config-yaml-shortcomings
自定义 PropertySourceFactory
从 Spring 4.3 开始,@PropertySource 带有工厂属性。我们可以利用它来提供我们对 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 读取解析的属性。
@PropertySource 和 YAML 实战
创建一个自定义 yaml 文件 custom.yml
server:
machine:
ip: 127.0.0.1
port: 20086
switches:
- on
- off创建一个配置类 CustomConfig
@Configuration
@Data
@PropertySource(value = "classpath:custom.yml", factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "server")
public class CustomConfig {
private Map<String,String> machine;
private List<String> switches;
}
class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public org.springframework.core.env.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);
}
}这里为了方便,直接将 YamlPropertySourceFactory 类和 CustomConfig 类写在一起了。
测试
@SpringBootTest
public class CustomConfigTest {
@Autowired
private CustomConfig customConfig;
@Test
public void configTest() {
System.out.println(customConfig.toString());
}
}结果:
CustomConfig(machine={ip=127.0.0.1, port=20086}, switches=[true, false])本文参考:
@PropertySource with YAML Files in Spring Boot
Inject a Map from a YAML File with Spring
评论已关闭