问题描述
在使用ConfigurationProperties读取自定义的hello.yml文件时,使用PropertySource注解指定文件时发现没有将配置文件中的数据注入,但是当将配置放在默认的application.yml文件时发现读取成功。
问题发生原因
PropertySource注解默认采用的读取方式是DefaultPropertySourceFactory,而DefaultPropertySourceFactory无法读取Yaml文件,因此可以利用PropertySource中的factory属性来指定使用的工厂,在工厂中通过YamlPropertySourceLoader方法来对配置文件进行解析。
使用@Component、@PropertySource和@ConfigurationProperties三个注解及一个实体类,可以实现读取自定义配置文件:
自定义工厂:
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
Resource resourceResource = resource.getResource();//先得到资源文件
System.out.println("resoureResource info");
if(!resourceResource.exists()){
System.out.println("resource not exist");
return new PropertiesPropertySource(null, new Properties());
} else if(
//判断得到的资源文件是否是yml文件
resourceResource.getFilename().endsWith(".yml") ||
resourceResource.getFilename().endsWith(".yaml")){
System.out.println("resourceResource = {}"+ resourceResource.getFilename());
//开始加载yaml文件
List<PropertySource<?>> sources = new YamlPropertySourceLoader()
.load(resourceResource.getFilename(),resourceResource);
return sources.get(0);
}
return super.createPropertySource(name, resource);
}
}
配置文件 hello.yml
main:
width: 200
height: 200
实体类
可以使用@value读取配置文件值,也可以使用set注入+ConfigurationProperties方式
@PropertySource(value = "classpath:hello.yml",factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix="main")
@Data
@ToString
@Component
public class TestProperties{
String width;
String height;
}
@Data
@ToString
@Component
public class TestProperties{
@Value("${main.width}")
String width;
@Value("${main.height}")
String height;
}
@RestController
public class PropertyController {
@Autowired
TestProperties testProperties;
@GetMapping("/testPro")
public String testDefinationObjYaml(){
System.out.println(testProperties);
return "testProperties";
}
}
成功注入读到:
补充:能读到第一层自定义的yaml文件的值,没有配置自定义配置工厂
先写自定义yaml文件:
hello.yml
hello: zidingyaml
main:
width: 200
height: 200
引入yaml文件并且把值赋给对应属性
@PropertySource(value = "classpath:hello.yml")
@Data
@ToString
@Component
public class TestProperties{
@Value("${hello}")
String width;
@Value("${hello}")
String height;
}
@RestController
public class PropertyController {
@Autowired
TestProperties testProperties;
@GetMapping("/testPro")
public String testDefinationObjYaml(){
System.out.println(testProperties);
return "testProperties";
}
}
结果没有保持:
第二种@Configuration、@PropertySource、@Bean和@ConfigurationProperties四个注解和一个配置类,一个实体类,实现读取自定义配置文件:
配置类
@Configuration
@PropertySource(value = "classpath:/hello.yml",factory = YamlPropertySourceFactory.class)
public class propertySourceConfig {
}
其余类跟上面配置一样即可