Get&Create Bean
2020-03-05 11:32:49 0 举报
Spring Bean 的加载过程
作者其他创作
大纲/内容
span style=\"font-size: inherit;\
根据条件决定是否提前暴露 bean 的早期引用(early reference),用于处理循环依赖问题
设置 beanInstance 到 BeanWrapperImpl 对象中
Object sharedInstance = getSingleton(beanName);懒加载一般在getBean时才实例化
根据需要进行FactoryBean的实例获取,以及类型转换。
earlySingletonExposure 是一个重要的变量,这里要说明一下。该变量用于表示是否提前暴露单例 bean,用于解决循环依赖。earlySingletonExposure 由三个条件综合而成,如下:条件1:mbd.isSingleton() - 表示 bean 是否是单例类型条件2:allowCircularReferences - 是否允许循环依赖条件3:isSingletonCurrentlyInCreation(beanName) - 当前 bean 是否处于创建的状态中earlySingletonExposure = 条件1 && 条件2 && 条件3 = 单例 && 是否允许循环依赖 && 是否存于创建状态中。
earlySingletonExposure的判断以及操作,是解决循环依赖
createBeanInstance
检测 bean 配置中是否配置了 lookup-method 或 replace-method,若配置了,则需使用 CGLIB 构建 bean 对象
完成
确定参数值列表(argsToUse)
创建 BeanWrapperImpl 对象
处理 lookup-method 和 replace-method 配置
进行余下的初始化工作,详细如下:1. 判断 bean 是否实现了 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware 等接口,并执行接口方法2. 应用 bean 初始化前置操作3. 如果 bean 实现了 InitializingBean 接口,则执行 afterPropertiesSet 方法。如果用户配置了 init-method,则调用相关方法执行自定义初始化逻辑4. 应用 bean 初始化后置操作另外,AOP 相关逻辑也会在该方法中织入切面逻辑,此时的 exposedObject 就变成了一个代理对象了
注册依赖记录registerDependentBean();
检测是否存在 depends-on 循环依赖,若存在则抛异常。
将 beanName 从 singletonsCurrentlyInCreation 集合中移除
在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器(方法:postProcessAfterInstantiation)一个修改bean 状态的机会。
通过“默认构造方法”的方式构造 bean 对象
参数类型转换
返回Bean
getMergedLocalBeanDefinition(beanName);合并父子BeanDefinition
有依赖
BeanWrapper 是一个基础接口,用于包裹 bean 实例。通过 BeanWrapper 的实现类可以方便的设置/获取 bean 实例的属性
将属性应用到 bean 对象中
若上一步后置处理返回的 bean 为空,则调用 doCreateBean 创建 bean 实例
应用 MergedBeanDefinitionPostProcessor 后置处理器相关逻辑
// 检查是否有 dependsOn 依赖,如果有则先初始化所依赖的 bean String[] dependsOn = mbd.getDependsOn();
调用实例化策略创建实例,默认情况下使用反射创建实例。如果 bean 的配置信息中包含 lookup-method 和 replace-method,则通过 CGLIB 增强 bean 实例
在 bean 初始化前应用BeanPostProcessor,若后置处理返回的 bean 不为空,则直接返回InstantiationAwareBeanPostProcessor
从缓存中获取 BeanWrapper,并清理相关记录
调用 initializeBean 方法完成余下的初始化工作
检测类的访问权限。默认情况下,对于非 public 的类,若没有可访问方法,这里会抛出异常。
调用createBean();
获取已解析的构造方法参数列表
注册销毁逻辑
在属性被填充后,给 InstantiationAwareBeanPostProcessor 类型的后置处理器(方法:postProcessProperties)一个修改bean 状态的机会。
根据名称或类型注入依赖
根据具体情况判断
没有父容器
若未命中缓存,则创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回
获取默认构造方法,通过无参构造方法创建 bean 对象
判断是否有父容器
instantiateBean
transformedBeanName();1、将别名转换为具体的实例名2、FactoryBean的&
调用getSingleton();
将 beanName 添加到 singletonsCurrentlyInCreation 集合中, 用于表明 beanName 对应的 bean 正在创建中
根据参数列表与构造方法匹配,优先选择public,获取相应的构造函数
getBean()
解析 bean 的类型
使用 GCLIG 创建 bean 对象
调用 populateBean 方法向 bean 实例中填充属性
如果上面设置 continueWithPropertyPopulation = false,表明用户可能已经自己填充了bean 的属性,不需要 Spring 帮忙填充了。此时直接返回即可
通过“工厂方法”的方式构造 bean 对象
populateBean
优化参数列表:比如@ConstructorProperties(value = {\"coolblog\
创建Bean实例,并会在创建完成后,将 bean 放入缓存 。
这个方法主要用于获取指定方法的方法数量 count,并根据 count 的值进行相应的处理。count = 0 时,表明方法不存在,此时抛出异常。count = 1 时,设置 MethodOverride 对象的`overloaded`成员变量为 false。这样做的目的在于,提前标注名称`mo.getMethodName()`的方法不存在重载,在使用 CGLIB 增强阶段就不需要进行校验,直接找到某个方法进行增强即可。
通过“构造方法自动注入”的方式构造 bean 对象
加载依赖bean
获取已解析的构造方法
有,去父容器中getBean()
通过 getObject 方法调用 createBean 方法创建 bean 实例
收藏
0 条评论
下一页