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 }

 

搞定!测试通过。

 

posted @ 2019-07-30 20:19  花花牛  阅读(9752)  评论(0编辑  收藏  举报