SpringBoot加载自定义yml文件
自定义配置文件(跟SpringBoot的application.yml同一目录下):
nlu-parse-rule: title: "NLU响应结果解析规则" desc: "解析NLU的识别文本(JSON)构建响应URL,注意当前yaml配置中key不用到下划线" rules: - busiDesc: "能耗业务1" busiCode: "nh1" firstMarch: - $.store.bicycle.color|red|= - $.appkey|7kfo5mdq5xnf6ofkfh76xda7lbccqgi7gzfhakyq|= secondMatch: - $.store.bicycle.color|NULL|<> - $.store.bicycle.color|NULL|<> returnValue: # url中占位符的真实替换值 - key1|$.store.bicycle.color - key2|$.store.bicycle.color - key3|$.store.bicycle.color
映射为对象,代码如下:
1 @Component 2 @PropertySource(value= {"classpath:rules.yml"}) 3 @ConfigurationProperties(prefix = "nlu-parse-rule") 4 @Data 5 public class NluRuleProperties { 6 private String title; 7 private String desc; 8 private List<NluRuleConfig> rules; 9 }
调试发现竟然不识别,
@PropertySource 不支持yml文件的对象转换,原因如下,看源码:他的默认构造工厂是PropertySourceFactory
1 @Target({ElementType.TYPE}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Repeatable(PropertySources.class) 5 public @interface PropertySource { 6 String name() default ""; 7 8 String[] value(); 9 10 boolean ignoreResourceNotFound() default false; 11 12 String encoding() default ""; 13 14 Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class; 15 }
而PropertySourceFactory默认就一个实现:实现properties配置文件的加载解析
public class DefaultPropertySourceFactory implements PropertySourceFactory { public DefaultPropertySourceFactory() { } public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException { return name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource); } }
因此,我们只要实现一个yml文件的工厂类即可,参考:https://mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files/
代码实现:
1 public class YamlPropertySourceFactory implements PropertySourceFactory { 2 @Override 3 public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException { 4 Properties propertiesFromYaml = loadYamlIntoProperties(resource); 5 String sourceName = name != null ? name : resource.getResource().getFilename(); 6 return new PropertiesPropertySource(sourceName, propertiesFromYaml); 7 } 8 9 private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException { 10 try { 11 YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); 12 factory.setResources(resource.getResource()); 13 factory.afterPropertiesSet(); 14 return factory.getObject(); 15 } catch (IllegalStateException e) { 16 // for ignoreResourceNotFound 17 Throwable cause = e.getCause(); 18 if (cause instanceof FileNotFoundException) 19 throw (FileNotFoundException) e.getCause(); 20 throw e; 21 } 22 } 23 }
搞定!测试通过。