Spring bean到底是如何创建的?(上)(二)

pivoteic
发布于 2022-6-15 17:12
浏览
0收藏

 

spring是如何解决循环依赖的?

 

三级缓存

* 第一级缓存 singletonFactories ,这getObject的时候会去对bean创建一个代理对象

* 第二级缓存 earlySingletonObjects ,这里是存储早期对象

* 第三级缓存 singletonObjects ,成熟的,彻彻底底可用的实例

 

假设A 和 B 产生循环依赖了。假设A正在创建,他在创建的实话会去往第一级缓存注册一个 ObjectFactory , 然后在属性赋值(后面会说的)阶段注入了B , 此时B 要按照Bean创建的流程进行创建,跟A一样注册一个 OjbectFactory(B的注册不重要,我是为了让大家清楚跟A创建流程一样),当B在属性赋值阶段的时候要注入A,此时会发现,A正在创建,于是乎他就会从 singletonFactories  拿出A的ObjectFactory ,调用getObject方法,获取到A(此时的A仅仅创建出来,处于早期的状态,不是一个完整的Bean,但是可能被代理了),然后将获取到的A放入到earlySingletonObjects ,然后把早期的A的bean注入B,然后B继续执行。B执行完之后,注入给A,然后A继续执行,执行到最后A完完全全创建好之后。会把singletonFactories 和earlySingletonObjects 缓存清空,在singletonObjects 中放入自己成熟的bean,这样A B 就都创建完成了,也就解决了循环依赖的问题。

 

如果出现循环依赖的问题,这里就会获取到bean,只不过这个bean还没有被初始化,仅仅只是实例化出来的而已,如果需要被代理,这里其实也会被代理

 

假设没获取到,那么此时往下走else,尝试从父容器中获取bean

Spring bean到底是如何创建的?(上)(二)-鸿蒙开发者社区

四、bean的实例化阶段

从这个阶段开始,bean就会一步一步被创建出来父容器也没有,就要自己去创建这个对象,在创建之前合并BeanDefinition 和 注册依赖的bean,@DependsOn注解就是在这个阶段发挥作用的

Spring bean到底是如何创建的?(上)(二)-鸿蒙开发者社区

接下来就是对bean的作用返回进行判断,从这里可以看出,其实spring对于bean的作用范围中的单例和多例其实是采用硬编码的方式来进行完成的,其余的bean的作用范围,比如在web环境中的bean作用域session、springcloud环境中的@RefreshScope注解等都是通过扩展org.springframework.beans.factory.config.Scope的实现来完成的。大家有兴趣可以看看SessionScope和RefreshScope这两个实现类。

Spring bean到底是如何创建的?(上)(二)-鸿蒙开发者社区

补充一点,肯定会有人好奇,我的代码明明没有动过,我的Controller一直在那,怎么做到的一个session一个Controller,其实原理很简单,就是你看见的Controller其实是个代理对象,每次调用的时候都会根据session的不同去重新创建一个新的真正的Controller对象去调用,这里涉及到spring aop的知识,有机会我们再讲。不过从这里可以看出,spring 的 ioc和aop是spring的核心功能,spring实现的其他机制,很多都是通过这两个特性展开的。

 

接着我们顺着创建单例bean继续往下看,把创建单例bean的重要的每个环节都看一遍,从这我们就开始深入bean的生命周期源码阶段。从createBean方法开始

 

a. bean class 的加载阶段

Spring bean到底是如何创建的?(上)(二)-鸿蒙开发者社区

因为可能是通过xml文件来声明bean的,所以要把bean class加载一下

 

文章转自公众号:三友的java日记

已于2022-6-15 17:12:43修改
收藏
回复
举报
回复
    相关推荐