首页 > 开发 > Java > 正文

详解Spring Boot 自定义PropertySourceLoader

2024-07-13 10:07:36
字体:
来源:转载
供稿:网友

SpringBoot 的配置文件内置支持 properties、xml、yml、yaml 几种格式,其中 properties和xml 对应的Loader类为 PropertiesPropertySourceLoader ,yml和yaml 对应的Loader类为 YamlPropertySourceLoader。

观察这2个类可以发现,都实现自接口 PropertySourceLoader 。所以我们要新增支持别的格式的配置文件,就可以通过实现接口 PropertySourceLoader 来实现了。

下面实现了一个 json 格式的配置文件 Loader类:

package com.shanhy.sboot.property;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import org.springframework.boot.env.PropertySourceLoader;import org.springframework.boot.json.JsonParser;import org.springframework.boot.json.JsonParserFactory;import org.springframework.core.env.MapPropertySource;import org.springframework.core.env.PropertySource;import org.springframework.core.io.Resource;/** * JSON格式配置文件加载器 *  * @author 单红宇(CSDN CATOOP) * @create 2017年4月20日 */public class JsonPropertySourceLoader implements PropertySourceLoader {  public String[] getFileExtensions() {    // 配置文件格式(扩展名)    return new String[] { "json" };  }  public PropertySource<?> load(String name, Resource resource, String profile) throws IOException {    // 处理机制参考PropertiesPropertySourceLoader    // 无论profile有没有值,底层都会尝试先执行 load(String name, Resource resource, null),所以这个地方之间判断等于null即可。    // 当前版本springboot-1.5.2(后续版本未知)详见 ConfigFileApplicationListener 的 445 行    if (profile == null) {      Map<String, Object> result = mapPropertySource(resource);      return new MapPropertySource(name, result);    }    return null;  }  /**   * 解析Resource为Map   *   * @param resource   * @return   * @throws IOException   *    * @author 单红宇(CSDN CATOOP)   * @create 2017年4月20日   */  private Map<String, Object> mapPropertySource(Resource resource) throws IOException {    if (resource == null) {      return null;    }    Map<String, Object> result = new HashMap<String, Object>();    JsonParser parser = JsonParserFactory.getJsonParser();    Map<String, Object> map = parser.parseMap(readFile(resource));    nestMap("", result, map);    return result;  }  /**   * 读取Resource文件内容为字符串   *   * @param resource   * @return   * @throws IOException   *    * @author 单红宇(CSDN CATOOP)   * @create 2017年4月20日   */  private String readFile(Resource resource) throws IOException {    InputStream inputStream = resource.getInputStream();    List<Byte> byteList = new LinkedList<Byte>();    byte[] readByte = new byte[1024];    int length;    while ((length = inputStream.read(readByte)) > 0) {      for (int i = 0; i < length; i++) {        byteList.add(readByte[i]);      }    }    byte[] allBytes = new byte[byteList.size()];    int index = 0;    for (Byte soloByte : byteList) {      allBytes[index] = soloByte;      index += 1;    }    return new String(allBytes, "UTF-8");  }  /**   * 处理map(map中可能还嵌套map,递归处理),最终输出一个非嵌套的map   *   * @param prefix   *      前缀   * @param result   *      处理后的map   * @param map   *      处理前的map   *    * @author 单红宇(CSDN CATOOP)   * @create 2017年4月20日   */  @SuppressWarnings("unchecked")  private void nestMap(String prefix, Map<String, Object> result, Map<String, Object> map) {    if (prefix.length() > 0) {      prefix += ".";    }    for (Map.Entry<String, Object> entrySet : map.entrySet()) {      if (entrySet.getValue() instanceof Map) {        nestMap(prefix + entrySet.getKey(), result, (Map<String, Object>) entrySet.getValue());      } else {        result.put(prefix + entrySet.getKey().toString(), entrySet.getValue());      }    }  }}

然后在 src/main/resources 中创建 META-INF/spring.factories 文件,内容为:

org.springframework.boot.env.PropertySourceLoader=/com.shanhy.sboot.property.JsonPropertySourceLoader

创建测试的配置文件 application.json

{  "custom": {    "property": {      "message": "测试数据"    }  }}

创建验证结果的 HelloController.Java

@RestControllerpublic class HelloController {  @Value("${custom.property.message:}")  private String customProperty;  @RequestMapping("/test")  public String test() {    return customProperty;  }}

启动工程服务,浏览器访问 http://localhost:8080/test 即可查看输出的结果为 “测试数据”;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表