bean生命周期+循环依赖完整执行情况之源码调用流程

为了增强记忆,为了更好的理解,把源码调用流程记录下来

这里以Aserivce和Bservice循坏依赖为例子

Aservice先创建
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
方法执行内容{
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String),先去找一级、二级、三级缓存中是否有对应的bean,这也是循坏依赖很重要的点,第一个类过来找那肯定是没有的,但是后面循坏依赖的时候就会存在三级缓存,并且会将三级缓存的objectfactory调用getObject方法实例化bean,并且移出三级缓存再加到二级缓存中

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
后面再去调用这个方法,传了一个ObjectFactory的实现类,直接new出来那种,然后进去发现这个类不在一级缓存,

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation,调用这个方法,将这个类表示为正在创建中的单例bean,存到一个集合里面,然后就会调用刚才传入的ObjectFactory,也就是下面的逻辑
}
-----》
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
方法执行内容{
获取到RootBeanDefinition mbdToUse,里面的内容包括bean的构造方法、生效范围(单例)、isFactoryBean(是否是工厂bean,也就是是否是生成代理对象)、autowireCandidate(是否是自动装配候选人)、primary(是否是主要的)

mbdToUse.prepareMethodOverrides()(设置方法是否被重载)

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(让 BeanPostProcessors 有机会返回一个代理而不是目标 bean 实例)
}
–》
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean核心方法创建bean
方法执行内容{
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance,实例化bean,会去寻找参数为空的构造方法进行实例化,如果没有空的那么就去找有参数的,但是找有参数的可能会提升生成这个参数所对应的bean,如果是无参构造主要走这个方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)真正调用无参实例化的方法,并且包装成BeanWrapper 类返回

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
走到这个方法之后有一个扩展点()
org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition(可以对合并后的beandedination进行处理,典型代表就是@Autowired和@PostConstruct的前置处理,会去检查是否有对应注解,并且缓存起来)
-----org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isSingletonCurrentlyInCreation,判断这个单例bean是否在创建中,这里肯定是创建中
这里是循环依赖的打印日志
急切地缓存 bean ‘aservice’ 以允许解决潜在的循环引用

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory,调用这个方法将SmartInstantiationAwareBeanPostProcessor都调用一次//用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配)
放到三级缓存Objectfactory,并且移出二级缓存
}

—》
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean,调用这个方法进行属性注入
方法执行内容{
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation通过接口字面意思翻译该接口的作用是感知Bean实例话的处理器。
https://cloud.tencent.com/developer/article/1409273

resolvedAutowireMode,判断自动装配模式是否是通过名称或者类型寻找,如果是这两个会调用autowireByName和autowireByType注入属性

org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessProperties,这个接口是postProcessPropertyValues的替代
在给bean注入属性的之前进行的操作(),循环依赖注入属性的实际入口

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties,开始为bean注入属性的处理入口,就是去找有没有带有@Autowired和@Value的注解的属性,这里会调用org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata方法并且会在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata这个方法中调用
org.springframework.util.ReflectionUtils#doWithLocalFields这个方法,将
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement创建保存到集合这个在后面调用这个对象的inject的方法的时候能找到这个参数

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject,调用这个内部参数的这个方法

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#resolveFieldValue,去这个参数进行解析,
-----org.springframework.beans.factory.config.AutowireCapableBeanFactory#resolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set<java.lang.String>, org.springframework.beans.TypeConverter)
调用这个方法,去解决bean参数的依赖问题,其实就是去找bean在不在,不在就创建

org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate

到这里就开始创建参数的bean,这时候又重新走到了doGetBean,去生成要注入的属性bService了
}

—》
接下来生成bService会一直往下走,也会先放到三级缓存里面,然后在注入属性的时候,发现了aService在三级缓存,这时候会把它拿出来,并且移出三级缓存,放到二级缓存,并且将aSerive注入到bService的属性当中具体的方法调的是org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean),这时候bservice在三级缓存,aservice在二级缓存
—》
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
然后就是调用初始化前-》初始化中org.springframework.beans.factory.InitializingBean继承这个接口
然后初始化后
—》
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#afterSingletonCreation,调用这个方法,将创建中该单例bean移出集合
—》
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton,调用这个方法,将bservice添加到一级缓存,移出二级和三级缓存
这时候bservice在一级缓存,aservice在二级缓存

—》
然后获取aservice的属性bservice拿到了,这时候给aservice注入Bservice,
又回到了
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
然后开始执行aservice的初始化前初始化中初始化后
再次调用
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
发现aservice在二级缓存,这时候直接拿出来,
然后再执行org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#afterSingletonCreation把aservice也从创建中集合移出
然后在调用
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
将aservicer也放到一级缓存,然后移出二级和三级缓存,到这里循环依赖解决了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值