spring循环依赖

着重观察refresh方法

前面七个方法是做一些准备工作,第八个方法是真正的spring创建bean开始。本文只介绍关键步骤

spring循环依赖_第1张图片
refresh方法流程

1.第一个方法

方法一

一个模板方法 允许子类实现beanfactory后置处理

2.第二个方法

方法二

调用beanfactory处理器

3.第三个方法

方法三

注册bean的后置处理器beanpostprocessor

4.第四个方法

方法四

初始化消息源

5.第五个方法

方法五

初始化应用实际事件发布的委托

6.第六个方法

方法六

一个模板方法 子类实现 可定义特定的刷新方法

7.第七个方法

方法七

查询监听器 并注册

8.第八个方法(重点)

方法八8-1

实例化所有非懒加载单利bean

8.1进入方法

spring循环依赖_第2张图片
8.1-1

红框之前是准备操作,红款真正开始创建bean 此处流程为创建第一个对象A

spring循环依赖_第3张图片
8.1-2

此处循环遍历所有的beanDefinition(里面记录了bean的基本信息是否懒加载是否单例等),先判断是否是factoryBean对象,如果不是就走创建bean方法,也就是红框,进入是重载方法

getbean重载方法

再次进入到实际执行方法,先尝试获取bean

spring循环依赖_第4张图片
尝试获取bean

getsingleton方法实现如下

spring循环依赖_第5张图片
getsingleton

首先从一级缓存singletonObjects中获取bean对象,如果没有则到二级缓存earlySingletonObjects获取对象,如果还是没有,则到三级缓存singletonFactories中查找,如果三级缓存存在,则清除三级缓存中的ObjectFactory对象,通过三级缓存查询的对象调用getObject方法生成的不完全的bean对象放入二级缓存。概念:一级缓存:执行完bean生命周期完整的bean对象。二级缓存:只执行了一部分beanpostprocessor的不完整的bean对象。三级缓存:bean对应的ObjectFactory是一个工厂对象。

spring循环依赖_第6张图片
getSingleton之后

此处会判断对象是否存在,如果存在则走getObjectForBeanInstance方法,此处第一次不存在,本方法下面再介绍。

spring循环依赖_第7张图片
getSingleton不存在

首先判断是否创建过,之后如果查不到beandefinition信息则到父类beanfactory获取

获取beandefinition

实例化bean对象,此处传入参数beanName以及一个lambda表达式

spring循环依赖_第8张图片
实例化bean对象

进入getSingleton,此处又是getSingleton一个重载方法

spring循环依赖_第9张图片
getSingletion

通过刚刚的lambda表达式调用getObject获取singletonObject

调用lambda表达式方法
spring循环依赖_第10张图片
lambda表达式方法

lambda表达式调用了createbean方法,进入creatbean方法

spring循环依赖_第11张图片
实例化之前处理器
spring循环依赖_第12张图片
具体实现

这边是判断是否需要生成代理对象而不是原对象,分为实例化之前和初始化之后。先看实例化之前。

spring循环依赖_第13张图片
实例化之前的操作

判断对象所有的beanpostprocessor,如果有实现了InstantiationAwareBeanPostProcessor接口的则执行生成代理操作,如果有实例化之前则会走初始化之后

spring循环依赖_第14张图片
初始化之后操作

初始化之后就是遍历执行bean后置处理器

设置属性

这边是设置bean是否做过实例化之前增强,如果这一步bean!=null则creatBean流程结束,如果为null则继续

spring循环依赖_第15张图片
doCreateBean方法

不需要实例化之前增强则会走正常的创建bean流程,进入

creatbean流程

首先从factoryBeanInstance获取bean获取不到则实例化对象

spring循环依赖_第16张图片
mergedBeanDefinition处理器

实例化之后 执行合并beandefinition类型的处理器,看一下此处理器的实现

spring循环依赖_第17张图片
mergedBeanDefinition子类实现

可以看到其中有autowired、定时任务、required等注解处理就在这一步

判断

此处判断是否是单例、是否允许循环依赖、是否是正在创建的对象

spring循环依赖_第18张图片
暴露自己方法

如果满足上述条件则会进入这个方法,同样的会传入一个beanName以及一个lambda表达式对应的是ObjectFactory对象

spring循环依赖_第19张图片
暴露自己具体

此处是将完成实例化的对象放入三级缓存,并清理二级缓存,并将beanName放入标记已注册set集合中,注意这里是实例化之后将自己暴露在三级缓存,所以如果是构造器注入则无法解决循环依赖。

spring循环依赖_第20张图片
实例化之后的操作

首先进入populateBean方法,此方法为填充属性的值

spring循环依赖_第21张图片
填充属性第一步

进入方法后会先执行实例化处理器的后置处理器操作也就是postProcessAfterInstantiation方法

spring循环依赖_第22张图片
填充属性第二步

1.判断是否注册instantiation处理器并执行;2.是否需要依赖检查,如果需要检查则会判断对应的类型是否被设置。

准备填充属性

执行准备填充属性

spring循环依赖_第23张图片
填充属性重要代码

返回一个传入属性的对象

spring循环依赖_第24张图片
创建属性对象方法

此处可以看到再次调用了getBean方法,进入

doGetBean

再次进入doGetBean方法,开始创建对象B

spring循环依赖_第25张图片
getSingleton

和创建A一样先从三级缓存中查询是否存在对象,后续流程和创建A一样,此处关注属性赋值

b进行属性赋值

此处也是走的doGetBean

spring循环依赖_第26张图片
a的getSingleton

此处第三级缓存中存有a的ObjectFactory对象

spring循环依赖_第27张图片
获取a对象

此处会走之前传入的lambda表达式

spring循环依赖_第28张图片
传入的lambda表达式
spring循环依赖_第29张图片
具体实现

此处主要是执行实现了smartInstantiationAwareBeanPostProcessor接口的处理器的方法,其中AbstractAutoProxyCreator类实现了此接口。主要是为了处理aop,这一步之后会讲代理对象放入二级缓存,并且删除三级缓存中的对象。

spring循环依赖_第30张图片
处理器调用的方法

此处将a放入了早期代理引用(早期代理引用指的是循环依赖中只执行了aop处理的不完整的bean)的set集合中,为了之后执行后置处理器不重复执行proxy。

spring循环依赖_第31张图片
此处为初始化后置处理器

补充:此方法是bean初始化后置处理器执行的aop增强的方法,这里会先到早期引用代理判断对象是否存在如果存在则不需要再做aop处理。

spring循环依赖_第32张图片
具体方法

此处为AbstractAutoProxyCreator实现接口之后的具体实现方法,主要就是获取所有的增强,并添加到标记是否需要增强的map中 设置为false(不需要) 

spring循环依赖_第33张图片
真正执行proxy方法

此处执行动态代理,cglib或者jdk并返回。然后属性赋值,完成b的创建(完整的bean),创建完成后会将二级三级缓存中的b清理,并放入一级缓存中。

spring循环依赖_第34张图片
初始化对象

回到A对象创建,分析一下属性赋值之后初始化的工作内容,进入方法

spring循环依赖_第35张图片
初始化执行步骤

可以清楚地看到初始化流程会先执行beanPostBeforeInitialiaztion然后执行invokeInitMethods最后执行beanPostAfterInitialiaztion

spring循环依赖_第36张图片
invokeInitMethods

其中invokeInitMethods方法中会先执行afterPropertiesSet然后才是initmethod。(@PostConstruct注解方法优于这两个方法) 

spring循环依赖_第37张图片
初始化之后

如果是标记循环依赖的对象则到二级或三级缓存获取对象,并返回,此时完成docreatbean方法。最后将完整的a的bean对象放入一级缓存并清空二级三级缓存。

2021-1-28----补充

补充一下@autowired装配。之前说到了mergedBeanDefinition类,这边会将需要autowired等注解进行记录

spring循环依赖_第38张图片
AbstractAutowireCapableBeanFactory.populateBean方法

在执行applyPropertyValues方法之前会先判断是否有实例化处理器以及是否需要自动注入,如果需要就会走如图判断,遍历所有处理器,并执行符合要求的

AutowiredAnnotationBeanPostProcessor类
spring循环依赖_第39张图片
AutowiredAnnotationBeanPostProcessor父类关系图

可以看出autowired注解处理器是InstantiationAwareBeanPostProcessor的子类,会走其中的逻辑。

spring循环依赖_第40张图片
AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues

首先获取到所有autowired的元数据,然后进行注入。

spring循环依赖_第41张图片
InjectionMetadata.inject

找出全部的element并逐个注入(如何解析出element的接下来讲)

spring循环依赖_第42张图片
AutowiredAnnotationBeanPostProcessor.inject

这边先查缓存,然后获取被依赖对象以及依赖对象以及类型,然后通过beanFactory的resolveDependency方法获取值

spring循环依赖_第43张图片
DefaultListableBeanFactory.resolveDependency

首先判断是不是必须的,是不是objectfactory,然后这边主要看最后一个else的内容,获取懒加载对象,如果没有则走doResolveDependency方法。

DefaultListableBeanFactory.doResolveDependency方法

这个方法中其他的也是一些判断和获取信息,主要看这行代码,就是加载所需要的类

spring循环依赖_第44张图片
DependencyDescriptor.resolveCandidate方法

到这里就可以看到熟悉的beanfactory.getBean方法了,然后就是走创建bean的流程了

如果我没猜错,等我在看几次,后续这个文章应该会有补充以及修改!

你可能感兴趣的:(spring循环依赖)