Spring Bean加载流程分析(通过 XML 方式加载)( 四 )
该方法的主要功能是为了从指定的 Resource 文件中加载 BeanDefinition , 该方法的返回值是返回 BeanDefinition 的数量 。 此处 Spring 将传入的 Resource 对象封装成了一个 EncodedResource 对象 。 顾名思义我们知道该对象只是对 Resource 进行了封装 , 其中除了包含指定的 Resource 资源外 , 还包含了编码信息 , 进入 EncodedResource 源码看看 。
public EncodedResource(Resource resource) {this(resource, null, null);}public EncodedResource(Resource resource, @Nullable String encoding) {this(resource, encoding, null);}public EncodedResource(Resource resource, @Nullable Charset charset) {this(resource, null, charset);}/** * 私有构造方法 **/private EncodedResource(Resource resource, @Nullable String encoding, @Nullable Charset charset) {super();Assert.notNull(resource, "Resource must not be null");this.resource = resource;this.encoding = encoding;this.charset = charset;}复制代码
可以看到 , Charset 和 encoding 是互斥的属性 。 显然我们这里仅仅只传入了 Resource 对象 , 那么默认的 encoding 了 charset 均为空 。
接下来看看 loadBeanDefinitions(EncodedResource e) 的具体实现 。
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {// .... 省略无效代码Set
resourcesCurrentlyBeingLoaded 是一个 ThreadLocal 对象 , 首先先从 resourcesCurrentlyBeingLoaded 中获取当前的 encodedResource , 如果获取出来的为空 , 则初始化一个 new HashSet
很显然这里面造成了一个循环引用 , 执行至此必然会抛出异常 。
文章插图
这里使用了一种巧妙的方式 , 通过 Set 集合不能有重复数据的特性来判断 applicationContext.xml 文件中的定义是否出现了循环导入 。
推荐阅读
- FlinkSQL 动态加载 UDF 实现思路
- 基于Spring+Angular9+MySQL开发平台
- 网络比15年前更慢错误更多?开发者加载了100万个网站实测
- 别不拿GateWay当回事,SpringCloud告诉你错了
- web 安全之 Spring Security 入门教程
- Spring Application实例化流程和构造方法参数
- SpringBoot常用注解
- 阿里爆款SpringBoot项目实战PDF+源码+视频分享
- Firefox 83将默认启用Warp更新:大幅提升响应时间和加载速度
- SpringCloud下skywalking的快速入门