共计 1653 个字符,预计需要花费 5 分钟才能阅读完成。
Date 10.06 pm
Point
完成 beanfactory 中单例 bean 的初始化
beanFactory.preInstantiateSingletons()
- 拿到所有的 bean 定义信息(在
beanDefinitionNames
中,遍历 list - 获取到 bean 的定义信息
- 如果这个 bean 不是抽象,是单例,不是懒加载的
-
判断这个 bean 是否 factorybean(判断这个 bean 有没有实现 factoryBean 接口),是的话,用工厂里面的方法去创建 bean。
- 调用
getbean(&beanname)
获取到 beanFactory 对象。
- 调用
-
调用
getBean(beanName)
创建 bean- 调用
doGetBean()
-
transformedBeanName
进入这个方法将之前工厂 bean 的前缀去除,将别名转成正式的名称 -
getSingleton
检测单例缓存中是否有已构建的单实例 bean,有就直接返回这个单例 bean/** Cache of singleton objects: bean name to bean instance. */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
所有实例过的单例 bean 都会在这注册,检查的时候还会判断当前 bean 有没有在创建过程中。如果有的话,会在
earlySingletonObjects
去获取,要是这个还是没有获取到的话,会去singletonFactories
这个 map 中去获取,要是获取到的话就删除singletonFactories
中的 bean,转而在earlySingletonObjects
这个 map 里面去注册 -
没有获取到 bean(开始创建 bean 的流程)
- 就先判断下我们是不是正在创建这个 bean 的实例,避免循环引用的问题。
- 获取 bean 的父工厂(这个主要是如果有 Springmvc 的话 可能会有这种父子工厂)这个父工厂要是能获取到的话,又会去调用父工厂的 dogetbean 方法,获取不到父工厂的话直接下一步
- 标记当前 bean 已经创建,大概就是把当前 beanname 放到
Collections.newSetFromMap(new ConcurrentHashMap<>(256))
里面,防止多线程的时候多次创建单例 bean - 获取 bean 的定义信息
- 获取 bean 所依赖的其他 bean,如果有,还是调用 getbean 的方式去构建那些依赖的 bean
-
如果这个 bean 是单例 bean,回掉
createBean
,开始单例 bean 创建- 拿到 bean 的定义信息
- 解析 bean 的定义的类型,检查这个定义信息中的 beanClass 是不是为空
- 检测是否有 bean 方法被重写,有的话准备重写这个 bean 方法(也是检查 bean 定义信息里面的
methodOverrides
这个属性有没有值) -
让 BeanPostProcessor 提前拦截,返回代理对象
resolveBeforeInstantiation()
- 先根据定义信息中的
beforeInstantiationResolved
判断初始化之前有没有处理,有的话就不进入这个 processor 中了, - 然后判断这个值是不是由 application 定义的 和 判断当前 factory 中已经有了
InstantiationAwareBeanPostProcessor
这个 processor 了,然后去获取这个 bean 的目标 class,然后调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
启动前置处理器,然后如果返回的 bean 有值的话,再调用applyBeanPostProcessorsAfterInitialization
后置处理器,然后将 bean 定义信息中beforeInstantiationResolved
这个参数赋值成这个返回的 bean,然后返回这个 bean
- 先根据定义信息中的
- 调用
https://github.com/fulln
正文完
发表至: java
2019-11-01