让@PropertySource支持Yaml

在某些特定的场景下,需要指定配置文件,而@PropertySource默认是不支持Yaml类型的配置文件的,因此,在这种情况下,通常只能将Yaml文件改写为properties文件来让@PropertySource识别。这里介绍一种方式来让@PropertySource支持Yaml格式的文件。

我们用一个测试环境的数据库连接配置文件进行测试:

spring:
  datasource:
    dynamic:
      primary: source
      strict: true
      datasource:
        source:
          url: jdbc:sqlserver://10.177.49.98:1433;DatabaseName=SFCTEST
          username: sa
          password: sadjaslds
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        center:
          url:  jdbc:sqlserver://10.177.49.98:1433;DatabaseName=CentralDatabase
          username: sa
          password: jsdabajkdasd
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

 首先来看默认的@PropertySource和@Value搭配读取指定Yaml文件的场景:

@Configuration
@PropertySource(value = "classpath:application-transfer.yml")
public class DruidConfig {
 
    @Value("${spring.datasource.dynamic.datasource.source.url}")
    private String sourceUrl;
    @Value("${spring.datasource.dynamic.datasource.source.username}")
    private String sourceUsername;
    @Value("${spring.datasource.dynamic.datasource.source.password}")
    private String sourcePassword;
    @Value("${spring.datasource.dynamic.datasource.source.driver-class-name}")
    private String sourceDriverClassName;
    @Value("${spring.datasource.dynamic.datasource.center.url}")
    private String centerUrl;
    @Value("${spring.datasource.dynamic.datasource.center.username}")
    private String centerUsername;
    @Value("${spring.datasource.dynamic.datasource.center.password}")
    private String centerPassword;
    @Value("${spring.datasource.dynamic.datasource.center.driver-class-name}")
    private String centerDriverClassName;

 如果直接这样写,在启动的时候会抛出如下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'druidConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.dynamic.datasource.source.url' in value "${spring.datasource.dynamic.datasource.source.url}"

 意思就是,解析不到这个spring.datasource.dynamic.datasource.source.url占位符所指定的值,而在上述Yaml文件中,很明显是有值的。这里的原因就在于,@PropertySource默认不支持Yaml文件,因此,读取的是默认配置文件,自然读取不到。

接下来做一些改造。我们需要一个新的propertySource工厂类,继承默认的DefaultPropertySourceFactory,实现Yaml的解析:

package com.aac.config.transfer;
 
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
 
import java.io.IOException;
import java.util.List;
 
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
 
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(),resource.getResource());
        return sources.get(0);
    }
}

 在这个新的工厂类中,重写createPropertySource方法,通过YamlPropertySourceLoader加载对应的yml文件,并返回解析之后的PropertySource对象。

而后,在需要支持Yaml读取的@PropertySource注解上指定factory即可,例如:

@PropertySource(value = "classpath:application-transfer.yml", factory = YamlPropertySourceFactory.class)

 即可完成正常的属性注入,如图:

 

posted @ 2020-10-15 16:07  猎喵Rachel  阅读(849)  评论(0)    收藏  举报