SpringBean加载
2022-03-31 14:50:07 5 举报
SpringBean创建流程,包含各后置处理器作用,循环引用的处理,三级缓存的操作,源码级别剖析加总结
作者其他创作
大纲/内容
获取早期引用
Start
AbstractAutowireCapableBeanFactory#createBeanInstance通过反射获取public无参构造器,如果没有就报错使用无参构造实例化,得到Bean实例
AbstractAutowireCapableBeanFactory#invokeCustomInitMethod如果Bean自己指定了init-method调用该用户指定初始化方法
遍历InstantiationAwareBeanPostProcessors调用其实例化前后方法,或许能直接返回一个对象
缓存中获取实例或早期引用
mbd.getScope
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
判断bean定义的范围
遍历BeanPostProcessor执行初始化前方法
AbstractAutowireCapableBeanFactory#createBean
传入匿名工厂工厂中#getObject调用方法createBean()
RootBeanDefinition#isPrototype定义为原型,即每次新建
AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor
优先获取实例一级缓存中获取singletonObjects.get
singletonsCurrentlyInCreation.add(beanName)把Bean设置为创建中
没有实例,创建实例#singletonFactory.getObject
如果trhis.singletonObjects有对象则返回如果this.earlySingletonObjects=有对象则返回都没有返回null
遍历BeanPostProcessor执行初始化后方法
DefaultSingletonBeanRegistry#getSingleton
if (!this.singletonObjects.containsKey(beanName)) span style=\"font-size: inherit;\
boolean earlySingletonExposure是否是早期暴露根据当前bean是否在创建中判断
遍历InstantiationAwareBeanPostProcessors调用其属性处理方法,可以对准备的属性值再调整
是
DefaultSingleBeanRegistry#getSingleton
continueWithPropertyPopulation
获取到实例
遍历InstantiationAwareBeanPostProcessors调用其实例化后方法,直到遍历完或某一个处理器返回false,即不需再装填属性
其次返回早期引用
没有返回对象
AbstractAutowireCapableBeanFactory#invokeInitMethods如果Bean实现了InitializingBean接口调用初始化方法afterPropertiesSet()
End
无需再装填属性
AbstractBeanFactory#registerDisposableBean如果需要就注册
AbstractAutowireCapableBeanFactory#doCreateBean创建Bean
总结:图中1、深蓝色块代表的是三级缓存的来回交替,可以看到一个Bean同一时刻只会在一个缓存中,因此三级缓存并非必须三级,分层主要还是为了责任清晰明确,各缓存代表不同的状态。其顺序为实例化Bean后存入工厂类放入三级缓存中,如果一切正常,将不会有机会再取出,而是使用实例化后的Bean直接赋值其初始化,最后放入一级缓存同时清空三级缓存。但如果存在循环引用,其他Bean需要装配该对象时,会将其从三级缓存取出早期对象,并放入二级缓存,最后返回该早期对象的引用去完成装配。注意,该早期对象后续会继续完成初始化等操作,最后完全体放入一级缓存同时清空二三级缓存,因此最终结束后,其他Bean装配的会是完全体对象2、天蓝色块则代表了代理(即切面增强)的生成,代理会在初始化后或早期引用被取出后生成,方法为wrapIfNecessary(),生成的代理对象将代替原对象放入三级缓存中,最后容器中存储的也是代理对象。巧妙地是,切面代理只能对方法增强,这意味着存在循环引用时,早期引用被取出被代理,最后代理被装配到其他Bean中时,尽管原始对象此时是半成品,但其代理本身已经功能完备,完成了对方法的增强。此时只需要等待原始对象完成属性装填-初始化等操作即可。3、红字线条各PostProcessor的作用位置及动作,其主要功能概括起来就是实例化前后 + 属性装填前后 + 初始化前后对Bean进行加工 ,特别的,实例化前其实没有Bean对象,因此实例化前加工更准确地说就是由PostProcessor自己去创建个对象并返回,该对象后续不会再做任何操作与加工,直接放入spring容器中4、Bean实例化流程简述:找到Bean定义 -> 利用反射找到其无参构造函数生成对象 -> 填充对象的属性 -> 执行初始化方法;上述流程配合各后置处理器的加工,最后形成完成的Bean@author:吃菠菜的太守
AbstractAutowireCapableBeanFactory#populateBean属性装填
DestructionAwareBeanPostProcessor#requiresDestruction
遍历DestructionAwareBeanPostProcessor校验该Bean是否需要有特殊销毁处理
暴露Bean
AbstractBeanFactory#getMergedLocalBeanDefinition
AbstractAutowireCapableBeanFactory#autowireByName#autowireByType获取自动注入的内容
AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor其初始化后方法postProcessAfterInitialization执行了#wrapIfNecessary完成代理类替换
从bean定义Map里获取Bean定义
返回建好的实例
AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary判断Bean是否需要注册销毁方法
获取bean定义中指定的属性值
AbstractBeanFactory#doGetBean
AbstractAutowireCapableBeanFactory#invokeAwareMethods如果Bean实现Aware接口,则执行该接口的方法
boolean earlySingletonExposure是否是早期暴露根据当前bean是否在创建中判断#singletonsCurrentlyInCreation.contains()
遍历SmartInstantiationAwareBeanPostProcessor使用其获取早期引用方法getEarlyRefernce包装Bean实例
AbstractAutowireCapableBeanFactory#initializeBean初始化内容
AbstractAutoProxyCreator#wrapIfNecessary如果Bean的类中有切面,则按照切面顺序创建多层次代理,最终返回代理类
RootBeanDefinition#isSingleton定义为单例类
获取单例
收藏
0 条评论
回复 删除
下一页