spring ioc
2020-09-01 17:06:01 132 举报
spring ioc
作者其他创作
大纲/内容
是否有依赖bean的对象
Y
T
N
遍历methodOverrides中的每一项
尝试从单例bean缓存(singletonObjects)获取
prepareMethodOverrides
getSingleton:尝试利用缓存获取bean
null
设置标志:该方法被重载
简单来看 bean的加载就是这几步:1.解析beanName2.尝试从缓存获取3.是否需要委托父factoryBean加载4.与父类bean合并属性5.加载@DependsOn的bean6.实例化并填充属性(这里涉及到了BeanPostPrecessor增强)7.获取对应bean8.类型转换
populateBean
调用BeanPostProcessor接口的前置处理器postProcessBeforeInstantiation
当前bean是单例&&允许循环依赖&&当前bean正在创建
getObjectForBeanInstance:将获取到的bean转换成doGetBean所需要的bean
再次从(factoryBeanObjectCache)缓存尝试获取一次
决定是否需要依赖检查(filterPropertyDescriptorsForDependencyCheck,checkDependencies)
没有父类
从earlySingletonObjects(早期bean)缓存中移除bean
ResolvedAutowireMode
从singletonFactories(单例工厂bean),earlySingletonObjects(早期bean)缓存中移除
Singleton
从当前正在创建的bean缓存(singletonsCurrentlyInCreation)中移除
doCreateBean
registerDisposableBeanIfNecessary
bean尚未被解析beforeInstantiationResolved
将bean加入到registeredSingletons(已注册缓存)中去
这里给BeanPostProcessor一个机会来返回覆盖掉bean(一般用来做bean的增强代理)
resolveBeanClass
bean的原始引用与增强后的bean是同一个
getMergedLocalBeanDefinition
beforePrototypeCreation:这里其实维护了一个ThreadLocal的set,用于存放所有正在创建的多例beanName,当有多例bean在创建的时候,在set中加入这个beanName
Prototype
createBean
Scope.get
当前bean正在创建(singletonsCurrentlyInCreation)
Exception:循环依赖
createBeanInstance
transformedBeanName: 将传入的name转换成合法的beanName(比如解析\"&\"等)。
baen
return
某个XX-method方法不存在
加载@DependsOn的bean:如果该bean有@DependsOn注解,即编码式依赖于其他bean,则spring会优先加载这个(些)依赖的bean
postProcessAfterInstantiation(实例化后处理器)增强
使用factoryBean获取bean,注意这是单例bean创建,因此它是个同步的方法
bean
exposedObject(增强后的bean)
获取早期bean(原始bean的引用)
用户自定义的bean(这里我们知道只有用户自定义的bean是需要在这里走BeanPostProcessor来做增强的)
createBeanInstance根据情况尝试采用instanceSupplier(Spring5.x新增),instantiateUsingFactoryMethod(工厂方法),autowireConstructor(带参构造函数),instantiateBean(默认构造函数)四种方式来创建一个bean实例(此时的bean实例属性值为null)
某个XX-method同名方法数量大于1(重载)
处理器返回结果为null
将bean从factoryBeanInstanceCache缓存移除
加入到已注册bean缓存(registeredSingletons)中去
isPrototypeCurrentlyInCreation:所有的多例bean在创建时都会存放到prototypesCurrentlyInCreation缓存,一旦在创建多例对象时发现自己位于这个缓存中,则判定为是循环依赖,抛出异常。
存放到缓存mergedBeanDefinitions中
beanName在自身的管理范围内
使用factoryBean生产需要的bean
将bean加入earlySingletonObjects缓存
doGetBean
resolveBeforeInstantiation
返回bean不为null
将父类属性合并到当前bean
尝试从mergedBeanDefinitions缓存获取
将解析后的属性填充到bean中
需要的bean是factoryBean
直接使用当前bean
AUTOWIRE_BY_NAME
initializeBean1.激活bean的Aware接口方法;2.使用BeanPostProcessor(postProcessBeforeInitialization和postProcessAfterInitialization)增强(可能会改变bean);3.调用自定义的init-method.
同步代码块:为每一个bean执行它的MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition增强
F
尝试从提前暴露的单例bean缓存(earlySingletonObjects)获取
获取对应的bean
当前bean加入到正在创建的缓存(singletonsCurrentlyInCreation)中去
几个比较重要的缓存对象:******************************************************************************singletonsCurrentlyInCreation:所有正在创建的bean+ getSingleton() 开始创建bean之前- getSingleton()创建完成bean之后+ getObjectForBeanInstance beanPostProcessor前- getObjectForBeanInstance beanPostProcessor后= getSingleton尝试从缓存加载bean,判断当前bean是否在创建************************************************************************************************************************************************************singletonObjects:单例缓存+ getSingleton 创建bean之后= getSingleton 尝试从缓存加载bean,判断当前bean是否已经在单例缓存中************************************************************************************************************************************************************factoryBeanObjectCache:factoryBean生产的bean缓存+ getObjectForBeanInstance 使用factoryBean创建对应的bean之后将这个bean存到缓存= getObjectForBeanInstance 需要bean时尝试从缓存中获取************************************************************************************************************************************************************earlySingletonObjects:早期bean对象(没有完全创建完成的bean,在spring中是实例化后的bean对象的引用,但是注意spring bean是可以通过增强器来产生代理bean的,这时候原始bean就可能与代理bean不同)+ getSingleton factoryBean生产后的bean加入到早期bean对象中- 使用BeanPostProcessor对bean增强后从早期bean缓存中移除= getSingleton 当前bean正在创建时,尝试现获取早期bean对象******************************************************************************
dlc再次尝试获取mergedBeanDefinitions
autowireByName
getSingleton
bean的原始引用和当前bean不相等
设置标志:该方法没有重载
Exception:对应XX-method方法不存在
isPrototypeCurrentlyInCreation
需要重新合并
尝试从factoryBean缓存(singletonFactories)中获取bean的生产工厂
resolveBeanClass:将当前的beanName转换成其对应的Class,同时将解析结果存放到bean definition中以便于后续使用
getSingleton()
从factoryBean缓存中移除这个工厂bean
Tips:使用前后置处理器的目的是对bean进行增强,可以在增强过程中选择是否创建bean的代理类。这个其实就是AOP的实现原理
getObjectForBeanInstance
Exception:循环依赖
Tips:判断bean的某个XX-method是否被重载式有用的,因为在调用这些方法的时候需要解析他们并且根据不同的入参结构调用不同的方法。
Tips:这里反复从factoryBeanObjectCache缓存中尝试获取bean,可见就算是直接利用factoryBean生产bean代价也是比较大的
将这个beanName对应的bean属性与父类合并以判断是否是用户自定义的bean
bean不为null
把当前bean移出正在创建的缓存(singletonsCurrentlyInCreation)
尝试从factoryBean生产的bean缓存(factoryBeanObjectCache)获取bean
afterPrototypeCreation
允许循环依赖
加载@DependsOn的bean
Exception:类型不匹配
加入到单例bean缓存(singletonObjects)中去
设置bean的Scope
从factoryBean生产的bean缓存(factoryBeanInstanceCache)中尝试获取bean
initializeBean
factoryBeanObjectCache(工厂生产的bean缓存)中加入这个bean
afterPrototypeCreation:将创建完成的beanName从当前正在创建的beanName Set中移除。
bean=getSingleton的返回bean
调用BeanPostProcessor接口的后置处理器postProcessAfterInitialization
增强返回结果
当前bean在singletonObjects(单例缓存)
用户自定义bean且实现了BeanPostProcessor
尝试委托父factoryBean加载
加入到当前正在创建的bean缓存(singletonsCurrentlyInCreation)中去
autowireByType
用户自定义bean且有InstantiationAwareBeanPostProcessor
convert Type类型转换
当前bean是factoryBean类型
得到bean的methodOverrides(存放bean的lookup-method和replace-method的Set对象)
AUTOWIRE_BY_TYPE
将bean加入到singletonFactories(单例factoryBean)缓存中
transformedBeanName
dcl再次从(factoryBeanObjectCache)缓存尝试获取一次
Scope
other
beforePrototypeCreation
0 条评论
回复 删除
下一页