专栏首页Nicky's blogSpringBoot源码学习系列之@PropertySource注解实现

SpringBoot源码学习系列之@PropertySource注解实现

因为yaml语法很简洁,比较喜欢写yaml配置文件,但是经过试验,@PropertySource默认不支持yaml读取,我们改成@Value注解也是可以读取的,不过属性一堆的话,一个一个读取也是很繁琐的,通过网上找资料和自己实验验证,发现是可以实现对yaml支持

然后,为什么@PropertySource注解默认不支持yaml文件读取?可以简单跟一下源码

@PropertySource源码:

根据注释,默认使用DefaultPropertySourceFactory类作为资源文件加载类

里面还是调用Spring框架底层的PropertiesLoaderUtils工具类进行读取的

PropertiesLoaderUtils.loadProperties

从源码可以看出也是支持xml文件读取的,能支持reader就获取reader对象,否则出件inputStream

load0方法是关键,这里加了同步锁

很重要的load0 方法抓取出来:

private void load0 (LineReader lr) throws IOException {
        char[] convtBuf = new char[1024];
        int limit;
        // 当前key所在位置
        int keyLen;
        // 当前value所在位置
        int valueStart;
        char c;//读取的字符
        boolean hasSep;
        boolean precedingBackslash;//是否转义字符,eg:/n etc.
		// 一行一行地读取
        while ((limit = lr.readLine()) >= 0) {
            c = 0;
            keyLen = 0;
            valueStart = limit;
            hasSep = false;

            //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
            precedingBackslash = false;
            //key的长度小于总的字符长度,那么就进入循环
            while (keyLen < limit) {
                c = lr.lineBuf[keyLen];
                //need check if escaped.
                if ((c == '=' ||  c == ':') && !precedingBackslash) {
                    valueStart = keyLen + 1;
                    hasSep = true;
                    break;
                } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {
                    valueStart = keyLen + 1;
                    break;
                }
                if (c == '\\') {
                    precedingBackslash = !precedingBackslash;
                } else {
                    precedingBackslash = false;
                }
                keyLen++;
            }
            //value的起始位置小于总的字符长度,那么就进入该循环
            while (valueStart < limit) {
                c = lr.lineBuf[valueStart];
                //当前字符是否非空格类字符
                if (c != ' ' && c != '\t' &&  c != '\f') {
                    if (!hasSep && (c == '=' ||  c == ':')) {
                        hasSep = true;
                    } else {
                        break;
                    }
                }
                valueStart++;
            }
            //读取key
            String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
            //读取value
            String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
            put(key, value);
        }
    }

ok,从源码可以看出,这个方法是一行一行地读取,然后根据冒号、等于号、空格等进行校验,经过一系列遍历之后获取key和value,而yaml语法是以缩进来辨别的,经过自己调试,这个方法也是不支持yaml文件的读取的,properties源码是比较多的,具体的Properties源码实现的可以参考博客:https://www.cnblogs.com/liuming1992/p/4360310.html,这篇博客写的比较详细

然后要支持的话,具体怎么实现,参考我博客:SpringBoot系列之@PropertySource读取yaml文件

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MyBatis关联查询(一对一)

    这里是一对一的关联关系,当然实际中一般不是这样的,一般可以是多对多,不过这里只是举例子

    SmileNicky
  • Redis学习笔记之分布式锁

    数据库锁 数据库本身提供了锁机制,比如乐观锁、悲观锁等等。下面给出我之前写的一篇博客,介绍一下mysql数据库的锁机制 Mysql的锁机制

    SmileNicky
  • 配置Eclipse可以查看JDK源码

    Window->Preferences->Java->Installed JREs

    SmileNicky
  • Python解答LeetCode

    古有科举八股,今有LeetCode。 八股定格式而取文采心意,LeetCode定题目且重答案背诵。 美其名曰:"practice makes perfec...

    SeanCheney
  • Jmeter吞吐量控制器详解

    吞吐量控制器(Throughput Controller)用来控制其下元件的执行次数,并无控制吞吐量的功能。 作用:控制其下的子节点的执行次数与负载比例分配

    橙子探索测试
  • 今日 Paper | 高效骨干搜索;学习扩充;最小人脸检测器;​DEPARA等

    论文名称:Efficient Backbone Search for Scene Text Recognition

    AI科技评论
  • CentOS 6下,service命令command not found问题的解决

    用户1456517
  • python——“破解”私有属性

    py3study
  • 梯度下降

    梯度下降(Gradient Descent)是在求解机器学习算法的模型参数(无约束优化问题)时,最常采用的方法之一 代价函数 提到梯度下降就不得不说一下代价函...

    听城
  • [日常] Go语言圣经--复数,布尔值,字符串习题

    1.我们把形如a+bi(a,b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位。两种精度的复数类型:complex64和complex128,...

    陶士涵

扫码关注云+社区

领取腾讯云代金券