盘点 SpringIOC Bean 创建主流程

总文档 :文章目录

Github : github.com/black-ant

一 . 前言

Spring IOC 体系是一个很值得深入和研究的结构 , 只有自己真正的读一遍 , 才能有更好的理解.

这篇文章主要说明一下 CreateBean 整个环节中的大流程转换 , 便于查找问题的原因 :

此篇文章的目的 :

  • 梳理Bean 的创建流程 , 便于后续查找问题点
  • 梳理过程中的参数情况 , 减少Debug的需求
  • 梳理整体家族体系

Bean 创建的几个触发场景 :

  • BeanFactory 的 #getBean(…) 方法来请求某个实例对象的时候
  • 使用 ApplicationContext 容器时 , 会在启动时立即注册部分 Bean

二 . 流程梳理

先来看一个很常见的图 , 来源于 @ topjava.cn/article/139…

beanSelf.jpg

同样的 , 这篇的流程整理也是按照此流程 , 先看一下整个流程大纲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
java复制代码> 实例化过程
1 实例化Bean 对象 : Spring 容器根据实例化策略对 Bean 进行实例化
?- 常用策略模式 , 通常包括反射和 CGLIB 动态字节码
- SimpleInstantiationStrategy : 反射
- CglibSubclassingInstantiationStrategy : 通过 CGLIB 的动态字节码 (默认)
- createBeanInstance(...) 方法实现 ,返回 BeanWrapper
- BeanWrapper : 低级 Bean 基础结构的核心接口
?- 低级 Bean : 无任何属性
- BeanWrapperImpl 对 Bean 进行“包裹” ,用于注入Bean 属性
|- InstantiationStrategy -> SimpleInstantiationStrategy
|- SimpleInstantiationStrategy -> CglibSubclassingInstantiationStrategy
2 注入对象属性
|- 实例化完成后,如果该 bean 设置了一些属性的话,则利用 set 方法设置一些属性
3 检测 , 激活 Aware
| -感知 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
|- 如果该 Bean 实现了 BeanNameAware 接口
|- 则调用 #setBeanName(String beanName) 方法
4 BeanPostProcessor 前置处理
|- 如果该 bean 实现了 BeanClassLoaderAware 接口
|- 则调用 setBeanClassLoader(ClassLoader classLoader) 方法。
|- 如果该 bean 实现了 BeanFactoryAware接口
|- 则调用 setBeanFactory(BeanFactory beanFactory) 方法
|- 如果该容器注册了 BeanPostProcessor
|- 则会调用#postProcessBeforeInitialization
|- 完成 bean 前置处理
5 检查 InitializingBean 和 init-method
|- 如果该 bean 实现了 InitializingBean 接口
|-则调用#afterPropertiesSet() 方法
|- 如果该 bean 配置了 init-method 方法,则调用其指定的方法。
6 BeanPostProcessor 后置处理
|- 初始化完成后,如果该容器注册了 BeanPostProcessor
|- 则会调用 #postProcessAfterInitialization,完成 bean 的后置处理。
7 注册必要的Destruction 回调
8 使用Bean
|- 对象完成初始化,开始方法调用
9 检查 DisposableBean 和 destory-method
|- 在容器进行关闭之前,如果该 bean 实现了 DisposableBean 接口
|- 则调用 #destroy() 方法
|- 在容器进行关闭之前,如果该 bean 配置了 destroy-method 
|- 则调用其指定的方法。

2.1 实例化创建

引言 : 谁调用的 ?

doGetBean 会有2种调用途径 :

一种是 ApplicationContext 加载的时候 , 会初始化当前容器需要的 Bean :

C- SpringApplication # run

C- SpringApplication # prepareContext

C- SpringApplication # applyInitializers : 调用 ApplicationContextInitializer 集合 , 分别执行对应的 initialize

C- ApplicationContextInitializer # initialize

C- ConditionEvaluationReport # get

C- AbstractBeanFactory # getBean

第二种是容器必要 Bean 加载完成后 ,refresh 时处理所有的 Bean

  • C- SpringApplication # run
  • C- SpringApplication # refreshContext
  • C- AbstractApplicationContext # refresh()
    • 此处refresh 中有多处会调用 getBean
    • C- AbstractApplicationContext # invokeBeanFactoryPostProcessors
    • C- AbstractApplicationContext # registerBeanPostProcessors
    • C- AbstractApplicationContext # onRefresh();
    • C- AbstractApplicationContext # finishBeanFactoryInitialization
  • C- AbstractBeanFactory # getBean

PS : 另外还有一种就是因为依赖关系被递归调用的

2.1.1 doGetBean 入口

1
2
3
java复制代码C171- AbstractBeanFactory 
M171_01- getBean(String name, Class<T> requiredType)
?- 直接调用 doGetBean , 这里会根据类型不同调用不同的 getBean

doGetBean 可以分为 5 个阶段

  • 阶段一 : 生成 beanName 后尝试从单例缓存中获取
  • 阶段二 : 单例缓存中获取失败后 ,尝试 ParentBeanFactory 中获取
  • 阶段三 : 依赖检查 , 保证初始化当前bean所依赖的bean
  • 阶段四 : 三种不同的类型获得 Bean 实例 (Singleton / prototype / other)
  • 阶段五 : 此时 Bean 已经准备完成了 , 此处检查所需的类型是否与实际bean实例的类型匹配 , 不符需要转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
java复制代码// 核心方法一 : 
M171_02- doGetBean( String name, Class<T> requiredType,Object[] args, boolean typeCheckOnly)

// 阶段一 : 生成 beanName 后尝试从单例缓存中获取
1- transformedBeanName 生成 beanName -> PS:M171_02_01
2- getSingleton(beanName) : 单例方式获取一个 Bean , 循环依赖就是这个环节处理 -> -> PS:M171_02_02
IF- sharedInstance != null : 如果此时已经生成 , 且 args 为空不需要继续加载
- getObjectForBeanInstance(sharedInstance, name, beanName, null)

// 阶段二 : 单例缓存中获取失败后 ,尝试 ParentBeanFactory 中获取
ELSE-
3- isPrototypeCurrentlyInCreation(beanName) : 如果是原型模式且存在循环依赖则抛出异常
4- getParentBeanFactory() : 检查这个工厂中是否存在bean定义
?- 如果工厂中已经存在了 , 会有四种情况会直接 return -> PS:M171_02_03
4.1- AbstractBeanFactory : parentBeanFactory.doGetBean
4.2- args != null : parentBeanFactory.getBean(nameToLookup, args)
4.3- requiredType != null: parentBeanFactory.getBean(nameToLookup, requiredType)
4.4- 都不符合 : parentBeanFactory.getBean(nameToLookup)
- 如果为类型检查而获取实例,而不是实际使用 , 则将指定的bean标记为已经创建 -> PS:M171_02_04
- RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName) + checkMergedBeanDefinition
?- RootBeanDefinition的获取和检查 LV171_001

// 阶段三 : 依赖检查 , 保证初始化当前bean所依赖的bean
- 对于属性 LV171_001:mbd , 通过 getDependsOn 获取所有依赖
FOR- 循环所有的依赖 , 分别调用 registerDependentBean + getBean 进行递归操作

// 阶段四 : 三种不同的类型获得 Bean 实例
5- 判断 Bean 的类型不同创建 Bean -> PS:M171_02_05
5.1- isSingleton : getSingleton + createBean + getObjectForBeanInstance
5.2- isPrototype : beforePrototypeCreation + createBean + afterPrototypeCreation + getObjectForBeanInstance
5.3- 其他 : 主要是通过 Scope 控制域 + Prototype 流程

// 阶段五 : 此时 Bean 已经准备完成了 , 此处检查所需的类型是否与实际bean实例的类型匹配
IF- 如果实例不匹配 , 则需要转换, 转换后直接返回
- return getTypeConverter().convertIfNecessary(bean, requiredType)
// 如果上面没有返回 , 则直接发返回原本的Bean


// 其他方法
M171_10- getSingleton(String beanName, ObjectFactory<?> singletonFactory) : 获取单例 Bean
M171_20- getObject() : 这里实际是调用 FactoryBean
?- 这里会通过一个 方法回调的语法糖 , 调用 createBean , 整个就连起来了 -> M173_02


// 核心方法二 : 实例化 Bean
// 首先要知道 , 前面传过来的是什么 : TODO
M171_ - getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd)


// PS : doGetBean 在附录中展示

2.1.2 doGetBean 补充节点

PS:M171_02_01 获取 beanName

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
java复制代码--> canonicalName(BeanFactoryUtils.transformedBeanName(name))
---->
C181- SimpleAliasRegistry
F181_01- Map<String, String> aliasMap
M- canonicalName(BeanFactoryUtils.transformedBeanName(name))
- 主要是从 F181_01 中获取 alias 别名
?- PS : 这里的代码有点意思 , 看样子是为了解决别名链的问题 , 即别名对应的还有别名 , 直到取不出来

public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
do {

resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
// 循环获取别名对应的是否存在别名 , 直到获取不到
}while (resolvedName != null);
return canonicalName;
}

PS:M171_02_03 为什么四种情况会直接返回 ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
java复制代码4.1- AbstractBeanFactory :  parentBeanFactory.doGetBean
4.2- args != null : parentBeanFactory.getBean(nameToLookup, args)
?- 使用显式参数委托给父类
4.3- requiredType != null: parentBeanFactory.getBean(nameToLookup, requiredType)
?- 委托给标准的getBean方法
4.4- 都不符合 : parentBeanFactory.getBean(nameToLookup)
?- Pro2

// 这里直接返回是因为存在父 BeanFactory , 且存在 BeanDefinition , 这就意味着ParentBeanFactory 能处理 , 基于 Pro 1 的原因 , 选择直接返回


// Pro 1 : 为什么从父工厂里面获取 -> BeanFactory parentBeanFactory = getParentBeanFactory();
这是一个递归操作 , 也是仿照双亲委派的方式来处理 , 即先有父对象来加载对应的对象

同样的 , 当进入 doGet 的时候 , 默认通过父方法去加载 , 如果父方法处理完成了 , 即加载出 Bean 了 , 就直接返回
好处呢 , 想了一下 , 可以保证每个实现能专注于其本身需要处理的 Bean , 而不需要关注原本就会加载的 Bean
回顾一下双亲委派的目的 : 避免重复加载 + 避免核心类篡改

// Pro 2 : 四种方式去返回的区别
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

PS:M171_02_04 对于只检查的那样处理有什么目的 ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
java复制代码    
这里如果是只检查而无需创建 , 会在 markBeanAsCreated 方法中做2件事
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);

这样的目的是为了即标注方法已经检查成功 , 而避免走没必要的反复流程 ,允许bean工厂为重复创建指定bean而优化其缓存
--> 实际逻辑

// Step 1 : alreadyCreated 是什么 ?
Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
?- alreadyCreated 包含 至少已经创建过一次的bean的名称的 Set 集合

// Step 2 : 如何利用这个对象 ?
1 : AbstractAutowireCapableBeanFactory # getTypeForFactoryBean
?- 这里会通过这个对象校验引用的工厂bean还不存在,那么在这里退出——不会仅仅为了获取FactoryBean的对象类型而强制创建另一个bean

2 : clearMetadata 时 , 需要判断是否为空

PS:M171_02_05 三种不同方式的本质区别 ?

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码相同点 :  最终调用 getObjectForBeanInstance    
5.1- isSingleton : getSingleton + createBean + getObjectForBeanInstance
- 首先通过 getSingleton 方法, 保证加载的唯一性
- 回调 createBean 创建 Bean
- 通过 getObjectForBeanInstance 实例化真正的 Bean

5.2- isPrototype : beforePrototypeCreation + createBean + afterPrototypeCreation + getObjectForBeanInstance
- 仔细看就能发现 , 没有相关的 scope 对象控制 , 直接进行创建

5.3- 其他 : 主要是通过 Scope 控制域 + Prototype 流程
- 它是 singleton 的结合体 ,
- 首先会准备一个 Scope 对象用于控制 Scope 域内的 Bean 情况
- 再调用和 Prototype 一致的流程进行创建

PS:M171_02_06 sharedInstance 和 bean 的区别

这里可以看到 , 首先通过 createBean 创建了一个 Object 对象 sharedInstance , 又通过 getObjectForBeanInstance 生成了一个 Bean ,他们有什么本质的区别 ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
JAVA复制代码if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

// 这就涉及到 Bean 的工厂了 , 一般情况下 , createBean 创建的 Bean 就是一个 完整的 Bean
// 但是 ,如果它是一个FactoryBean,需要使用它来创建一个bean实例,除非调用者实际上想要一个对工厂的引用。

sharedInstance 中的 Bean 是已经走完 Bean 创建流程的 Bean了
image.png

2.1.3 AbstractBeanFactory # createBean

1
2
3
4
java复制代码C171- AbstractBeanFactory 
M171_03- createBean(String beanName, RootBeanDefinition mbd, Object[] args) 
P- mbd : BeanDefinition 对象 , 已经合并了父类属性
p- args : 用于构造函数或者工厂方法创建 Bean 实例对象的参数

2.1.4 AbstractAutowireCapableBeanFactory # createBean 主流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
java复制代码C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
M173_02- createBean(String beanName, RootBeanDefinition mbd,Object[] args)
?- M170_01 方法的默认实现
LV173_02_01- RootBeanDefinition mbdToUse : 内部属性 , 用于标识根 BeanDefinition
1- Class<?> resolvedClass = resolveBeanClass(mbd, beanName) -> PS:M173_02_01
?- 解析获得指定 BeanDefinition 的 class 属性 -> M173_04
IF- 解析的 Class 不为 null , 且存在 BeanClass 和 BeanClassName
- new RootBeanDefinition(mbd)
- mbdToUse.setBeanClass(resolvedClass)
2- mbdToUse.prepareMethodOverrides() : 处理 Overrides 属性 -> PS:M173_02_02
- GetMethodOverrides().getOverrides()
- prepareMethodOverride(MethodOverride mo)
3- Object bean = resolveBeforeInstantiation(beanName, mbdToUse) --- 实例化的前置处理
- 如果 bean 不为 null , 则直接返回 (直接返回是因为上一步生成了一个代理类 ,AOP )
4- Object beanInstance = doCreateBean(beanName, mbdToUse, args); --- 创建对象
M173_03- createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
M173_04- resolveBeanClass : 将bean类名解析为class引用



// PS:M173_02_01 RootBeanDefinition
// 确保bean类在此时被实际解析,如果动态解析的class不能存储在共享合并bean定义中,则克隆bean定义
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// PS:M173_02_02 prepareMethodOverrides 处理 Overrides
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}

// >>>>>>> 对应 prepareMethodOverride 方法
C- AbstractBeanDefinition
M- prepareMethodOverride(MethodOverride mo)
1- ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName())
?- 获取当前Method Name 对应的方法数量
2- 如果没有对应方法 ,抛出 BeanDefinitionValidationException
3- 如果 count = 1 , 将 Overloaded 标记为未重载 , 在后续调用的时候,可以直接找到方法而不需要进行方法参数的校验


// M173_02 源码简介
M- createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
- beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
- beanInstance = this.doCreateBean(beanName, mbdToUse, args); -> M173_05

doCreateBean 主流程

doCreate 分为几大步骤 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
java复制代码 C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory   
M173_05- doCreateBean(beanName, mbdToUse, args) : 创建 Bean 对象
?- 非代理对象的 常规Bean 创建 , 主要节点有以下几个
- 准备 BeanWrapper : BeanWrapper 是对 Bean 的包装
- 如果单例模型,则从未完成的 FactoryBean 缓存中删除
- createBeanInstance(beanName, mbd, args) : 进入Bean 创建流程 , 创建一个 Bean 的封装 BeanWrapper
?- 这里的获取如果是单例 , 则直接获取 , 并且移除缓存中的对象
?- 否则调用 createBeanInstance 获取
- instanceWrapper.getWrappedInstance();
?- 包装的实例对象
- instanceWrapper.getWrappedClass();
?- 包装的实例对象的类型
IF- applyMergedBeanDefinitionPostProcessors
?- 如果有后置处理 , 则在此处进行后置处理 , synchronized 上锁
IF- addSingletonFactory
?- 如果是单例 , 且允许+ 存在循环依赖 , 则在此处进行单例模式的处理
- populateBean : 属性注入操作 -> M173_30
- initializeBean : 初始化 Bean
?- 此处会进行 Init-Method 的处理 -> PS:M173_05_03
IF- getSingleton
?- 循环依赖情况 , 则会递归初始依赖 bean , 此处返回的是一个用于循环处理的空对象
?- 2种情况 , 返回早期对象或者 getDependentBeans 递归所有的 -> PS:M173_05_01
- registerDisposableBeanIfNecessary
M173_07- prepareMethodOverrides
- 获取所有的 Overrides , 并且依次调用 prepareMethodOverride -> M173_08

M173_08- prepareMethodOverride
- getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride)
?- Foreach 所有的 Overrides , 调用 prepareMethodOverride
M173_10- autowireByName : 根据属性名称,完成自动依赖注入
M173_11- autowireByType : 根据属性类型,完成自动依赖注入
- resolveDependency -> resolveDependency
M173_12- resolveDependency : 完成了所有注入属性的获取
- doResolveDependency
M173_13- doResolveDependency
M173_15- applyPropertyValues : 应用到已经实例化的 bean 中
M173_50- initializeBean



// doCreateBean 核心代码流程
M- doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) : createBean 主流程
- mbd.isSingleton() : 判断后获取 BeanWrapper (ConfigurationClassPostProcessor)
- instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
- instanceWrapper = this.createBeanInstance(beanName, mbd, args);
- this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
- this.populateBean(beanName, mbd, instanceWrapper) : 主要是属性填充
- Step 1 : bw == null&&mbd.hasPropertyValues() : BeanWrapper 空值判断
- Step 2 : this.getBeanPostProcessors().iterator() : 迭代BeanPostProcessors
- ibp.postProcessAfterInstantiation : 此处是 After
- Step 3 : 获取 PropertyValue , 并且通过 autowireByName 或者 autowireByType 注入
- Step 4 : hasInstantiationAwareBeanPostProcessors
- this.getBeanPostProcessors().iterator();
- ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
- Step 5 :
- Step 6 : this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs) : 依赖检查
- Step 7 : this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs) :
- this.initializeBean(beanName, exposedObject, mbd);
- this.registerDisposableBeanIfNecessary(beanName, bean, mbd);


// 附录 : M173_05 doCreateBean 源码比较长 ,放在结尾

PS:M173_05_01 : 递归循环细说

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
java复制代码
在 doCreateBean 中 , 会对循环依赖进行处理

// 循环依赖情况 , 则会递归初始依赖 bean , 此处返回的是一个用于循环处理的空对象
// 2种情况 , 返回早期对象或者 getDependentBeans 递归所有的
if (earlySingletonExposure) {
// 参考循环依赖那一章 , 这里可能会返回一个未完善的前置对象引用
// 只有存在循环依赖 , 这里才不会为空
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
// 判断存在循环依赖
}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 返回依赖于指定bean的所有bean的名称(如果有的话)
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 如果有被用于类型检查之外的其他目的时 ,则不可以删除 -> PS:M173_05_03
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 无需删除 , 则添加
actualDependentBeans.add(dependentBean);
}
}
// 因为上文添加 , 这里就形成依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(".....");
}
}
}
}

// PS:M173_05_03 : 什么是其他的目的 ?
removeSingletonIfCreatedForTypeCheckOnly 核心是校验 alreadyCreated
1 . 如果 alreadyCreated 已经存在了 ,则说明对应的对象已经创建完成了
2 . 如果对应的对象已经创建完了了 , 其中依赖的当前对象不是正在创建的对象
3 . 但是其中的属性又不是当前的对象 , 说明循环依赖不成立 , 依赖已经串了

@ https://www.cnblogs.com/qinzj/p/11485018.html

M173_05 doCreateBean 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
java复制代码protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {

// Step 1 : 准备 BeanWrapper : BeanWrapper 是对 Bean 的包装
BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {
// 如果单例模型,则从未完成的 FactoryBean 缓存中删除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 进入Bean 创建流程 , 创建一个 Bean 的封装 BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取包装的实例对象
final Object bean = instanceWrapper.getWrappedInstance();
// 包装的实例对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// Step 2 : 如果有后置处理 , 则在此处进行后置处理 , synchronized 上锁
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException("....");
}
mbd.postProcessed = true;
}
}

// Step 3 :如果是单例 , 且允许+ 存在循环依赖 , 则在此处进行单例模式的处理
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Step 4 : 此处会进行 Init-Method 的处理 -> PS:M173_05_03
Object exposedObject = bean;
try {
// Step 5 :属性注入操作 -> M173_30
populateBean(beanName, mbd, instanceWrapper);
// Step 6 : 初始化 Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException("....");
}
}


// 循环依赖情况 , 则会递归初始依赖 bean , 此处返回的是一个用于循环处理的空对象
// 2种情况 , 返回早期对象或者 getDependentBeans 递归所有的 -> PS:M173_05_01
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(".....");
}
}
}
}

// Step 7 : 注册 Bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException("...");
}

return exposedObject;
}

总结

其中有几个锚点 :

Step 1 : 入口

入口中主要是会统筹管理 , 如果缓存中有 , 则直接使用 , 如果没有 , 则区别 Scope 分别使用不同的方式获取一个 Bean

1
2
java复制代码- C171- AbstractBeanFactory 
- M171_02- doGetBean

Step 2 : 创建主流程

创建主流程就是创建一个完整的 Bean , 走一个 Bean 创建的完整周期 , 包括 process , 属性注入 , init 初始化等等 , 这些我们在后面的文章中再详细说说

1
2
3
4
5
6
7
java复制代码// Step 1 : 
C173- AbstractAutowireCapableBeanFactory
M173_02- createBea

// Step 2 :
C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
M173_05- doCreateBean

附录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
java复制代码protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

// 阶段一 : 生成 beanName 后尝试从单例缓存中获取
final String beanName = transformedBeanName(name);
Object bean;

// 单例方式获取一个 Bean , 循环依赖就是这个环节处理 -> -> PS:M171_02_02
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 直接从实例化中获取 Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
// 阶段二 : 单例缓存中获取失败后
if (isPrototypeCurrentlyInCreation(beanName)) {
// 如果是原型模式且存在循环依赖则抛出异常
throw new BeanCurrentlyInCreationException(beanName);
}

// 检查这个工厂中是否存在bean定义
BeanFactory parentBeanFactory = getParentBeanFactory();

// 如果工厂中已经存在了 , 会有四种情况会直接 return -> PS:M171_02_03
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}

// 如果为类型检查而获取实例,而不是实际使用 , 则将指定的bean标记为已经创建 -> PS:M171_02_04
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
// RootBeanDefinition的获取和检查 LV171_001
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// 阶段三 : 依赖检查 , 保证初始化当前bean所依赖的bean
// 对于属性 LV171_001:mbd , 通过 getDependsOn 获取所有依赖
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 循环所有的依赖 , 分别调用 registerDependentBean + getBean 进行递归操作
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(.....);
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(.....);
}
}
}

// 阶段四 : 三种不同的类型获得 Bean 实例
// 判断 Bean 的类型不同创建 Bean -> PS:M171_02_05
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(....);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// 阶段五 : 此时 Bean 已经准备完成了 , 此处检查所需的类型是否与实际bean实例的类型匹配
// 如果实例不匹配 , 则需要转换, 转换后直接返回
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 如果上面没有返回 , 则直接发返回原本的Bean
return (T) bean;
}

参考与感谢

写这个之前 , 还跑过去再读了一遍 , 很感谢死磕系列开启了 IOC 的源码学习

-> @ topjava.cn/article/139…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%