【基础系列】SpringBoot配置篇之PropertySource加载Yaml配置文件实例演示 您所在的位置:网站首页 springboot扫描不到yml 【基础系列】SpringBoot配置篇之PropertySource加载Yaml配置文件实例演示

【基础系列】SpringBoot配置篇之PropertySource加载Yaml配置文件实例演示

2024-07-12 21:55| 来源: 网络整理| 查看: 265

文章目录 I. 项目环境1. 基本配置2. 实例项目II. PropertySource原理分析1. 源码定位2. yaml文件支持3. 小结III. 其他0. 项目1. 一灰灰Blog

在之前有介绍过借助注解@PropertySource来引入自定义的配置文件,在当时遇到抛出了一个问题,通过这个注解可以正确获取到.properties文件的配置信息,但是yaml文件却读取不到,最近又碰到这个问题,正好把之前挖的坑填上;本文将主要定位一下,为啥yml文件读取不了,又可以如何处理

如对之前博文有兴趣的小伙伴,可以查看: 180921-SpringBoot基础篇配置信息之自定义配置指定与配置内引用

I. 项目环境1. 基本配置

本文后续的源码定位以及实例演示都是基于SpringBoot 2.2.1.RELEASE进行,如需复现本文中的case,请确保环境一致

IDEA MAVEN SpringBoot 2.2.1.RELEASE JDK1.8 2. 实例项目

创建一个SpringBoot项目,用于后续的演示,首先创建一个配置文件biz.properties

123456biz.token=mytokenbiz.appKey=asdfbiz.appVersion=1biz.source=xxx.yyybiz.uuid=${biz.token}#${biz.appKey}

接下来定义对应的配置类

1234567891011@Data@Configuration@PropertySource({"classpath:biz.properties"})@ConfigurationProperties(prefix = "biz")public class OtherProperBean { private String token; private String appKey; private Integer appVersion; private String source; private String uuid;}

最后补上SpringBoot项目不可获取的启动类

123456789/** * Created by @author yihui in 14:08 18/9/19. */@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class); }} II. PropertySource原理分析

想要定位为啥@PropertySource注解只会获取到properties文件的配置,而不能获取yaml文件配置信息,最直接的办法当然是直接撸源码(实际上最简单的办法直接借助搜索引擎,看一下有没有哪位大佬有过相关分享,如果不是为了写本文,我可是完全没想开撸,毕竟从提出这个问题到现在回复,也过了两年多了😭…)

1. 源码定位

那么这个源码可以怎么定位分析呢,先直接进入这个注解瞅一下

12345public @interface PropertySource { // ... 省略无关的属性 Class createPropertySource(@Nullable String name, EncodedResource resource) throws IOException { return (name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource)); }}

在这里我们打个断点,确认一下会发生什么神器的事情

从上面的截图可以看到,这个EncodedResource包含了我们指定的配置文件,直接单步进去,可以看到执行的时候下面这个

12345// org.springframework.core.io.support.ResourcePropertySource#ResourcePropertySource(org.springframework.core.io.support.EncodedResource)public ResourcePropertySource(EncodedResource resource) throws IOException { super(getNameForResource(resource.getResource()), PropertiesLoaderUtils.loadProperties(resource)); this.resourceName = null;}

请注意,核心代码不是super()这个构造方法,而是传参的PropertiesLoaderUtils.loadProperties(resource)

上面这一行调用,就是实现具体的从配置文件中获取配置信息

下面是具体的实现(摘抄有用的部分逻辑)

123456789101112131415161718192021222324252627282930313233343536// org.springframework.core.io.support.PropertiesLoaderUtilspublic static Properties loadProperties(EncodedResource resource) throws IOException { Properties props = new Properties(); fillProperties(props, resource); return props;}public static void fillProperties(Properties props, EncodedResource resource) throws IOException { // 属性填充,注意DefaultPropertiesPersister fillProperties(props, resource, new DefaultPropertiesPersister());}static void fillProperties(Properties props, EncodedResource resource, PropertiesPersister persister) throws IOException { ... try { String filename = resource.getResource().getFilename(); if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { stream = resource.getInputStream(); // 这个是关键 persister.loadFromXml(props, stream); } else if (resource.requiresReader()) { reader = resource.getReader(); // 关键调用 persister.load(props, reader); } else { stream = resource.getInputStream(); // 关键调用 persister.load(props, stream); } } ...}

配置信息的读取,最终依靠的就是org.springframework.util.DefaultPropertiesPersister#load(),到这里我们基本上就找到了从配置文件中读取配置的“幕后黑手”,直接看一下它的实现逻辑就能知道为啥不支持yaml了

123456789101112public class DefaultPropertiesPersister implements PropertiesPersister { @Override public void load(Properties props, InputStream is) throws IOException { props.load(is); } @Override public void load(Properties props, Reader reader) throws IOException { props.load(reader); }}

直接进入看到源码,非常简单直观的实现方式了,直接使用jdk的java.util.Properties#load(java.io.InputStream)来读取配置文件,所以真相已经大白了(原来都是jdk的锅😂)

2. yaml文件支持

经过上面的一番操作,我们知道@ConfigurationProperties加载配置文件,主要是借助jdk的Properties#load方法来读取配置文件到容器内,那么若我们希望加载yaml配置文件,可以怎么搞呢?

因为SpringBoot是支持yaml配置文件的读取的,所以我们完全可以扩展一下,借助SpringBoot的工具类来实现配置文件加载,所以可以实现自定义的PropertySourceFactory

12345678910111213public class YamlSourceFactory extends DefaultPropertySourceFactory { @Override public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { if (resource == null) { return super.createPropertySource(name, resource); } // 这里使用Yaml配置加载类来读取yml文件信息 List


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有