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 }

 

搞定!測試通過。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章