全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

详解Spring Boot 自定义PropertySourceLoader

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

@RestController
public class HelloController {

  @Value("${custom.property.message:}")
  private String customProperty;

  @RequestMapping("/test")
  public String test() {
    return customProperty;
  }
}

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

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


# propertysourceloader  # Spring  # Boot 


相关文章: 济南企业网站制作公司,济南社保单位网上缴费步骤?  教育培训网站制作流程,请问edu教育网站的域名怎么申请?  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  寿县云建站:智能SEO优化与多行业模板快速上线指南  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  股票网站制作软件,网上股票怎么开户?  常州企业建站如何选择最佳模板?  如何快速搭建高效简练网站?  建站主机如何安装配置?新手必看操作指南  SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?  网站制作公司,橙子建站是合法的吗?  实例解析Array和String方法  视频网站app制作软件,有什么好的视频聊天网站或者软件?  宝塔新建站点报错如何解决?  5种Android数据存储方式汇总  无锡营销型网站制作公司,无锡网选车牌流程?  如何基于云服务器快速搭建网站及云盘系统?  如何通过可视化优化提升建站效果?  建站之星安全性能如何?防护体系能否抵御黑客入侵?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  建站主机服务器选型指南与性能优化方案解析  实例解析angularjs的filter过滤器  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  ,怎么用自己头像做动态表情包?  如何基于PHP生成高效IDC网络公司建站源码?  广州商城建站系统开发成本与周期如何控制?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  如何通过VPS搭建网站快速盈利?  建站之星如何助力网站排名飙升?揭秘高效技巧  网页设计网站制作软件,microsoft office哪个可以创建网页?  C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)  建站之星如何快速生成多端适配网站?  如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法  建站主机助手选型指南:2025年热门推荐与高效部署技巧  c# 在ASP.NET Core中管理和取消后台任务  建站主机服务器选购指南:轻量应用与VPS配置解析  建站ABC备案流程中有哪些关键注意事项?  整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?  如何高效生成建站之星成品网站源码?  购物网站制作公司有哪些,哪个购物网站比较好?  江苏网站制作公司有哪些,江苏书法考级官方网站?  建站之星客服服务时间及联系方式如何?  完全自定义免费建站平台:主题模板在线生成一站式服务  香港服务器网站卡顿?如何解决网络延迟与负载问题?  建站之星五站合一营销型网站搭建攻略,流量入口全覆盖优化指南  广州营销型建站服务商推荐:技术优势与SEO优化解析  如何通过.red域名打造高辨识度品牌网站?  小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  如何通过主机屋免费建站教程十分钟搭建网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。