Spring IOC 源码简单分析 02 - Bean Reference
### 准备
## 目标
##测试代码

</beans>
### 分析
## BeanFactory.getBean 流程分析
- 尝试从 Map<String, Object> singletonObjects 中获取名字为 chairman 的 bean 实例,当然,获取不到。
- 将 bean 标记为已创建(或即将创建完成)状态。就是将 chairman 放到 Set<String> alreadyCreated 中。
- 根据 BeanDefinition 生成 RootBeanDefinition。- Root bean: class [gordon.study.spring.common.Employee]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [ioc/ioc02.xml]
- 将 RootBeanDefinition 放到 Map<String, RootBeanDefinition> mergedBeanDefinitions 中。
- 根据 RootBeanDefinition 解析出 bean class,对于本例,是把 bean class name "gordon.study.spring.common.Employee" 解析为对应的 Class 实例。
BeanDefinition 有个属性 Object beanClass 用来记录 bean 定义对应的类类型,在前4步,其值为字符串 "gordon.study.spring.common.Employee",现在通过 resolveBeanClass 方法,将之修改为 Employee 类对应的 Class 实例。
实际的解析工作交给工具类 org.springframework.util.ClassUtils 的 forName 方法(暂不深入,调用栈见下图)。
通过 forName 方法得到 Class 实例后,框架将 Class 实例赋给 Object beanClass 属性以取代原来的字符串。这样,对于该 BeanDefinition,以后就可以直接获得其对应的 Class 实例了。
- 解析出用来创建实例的构造器,设置成 BeanDefinition 的 Object resolvedConstructorOrFactoryMethod 属性。对于本例,是默认构造函数。
- 使用该构造器通过反射机制创建 Employee 实例。
- 用 org.springframework.beans.BeanWrapper 包装新创建的 Employee 实例。
- 接下来要装配属性。populateBean 方法负责装配属性。
BeanDefinition 的 MutablePropertyValues propertyValues 属性在解析 XML 配置文件时就已经设置好。对于本例,配置文件中的 chairman bean 的 name 和 company 属性分别对应一个 PropertyValue 存在于 MutablePropertyValues propertyValues 的 List<PropertyValue> propertyValueList 属性中。
org.springframework.beans.PropertyValue 的核心属性是 String name 和 Object value,其中 value 有多种可能类型,在本例中,name 属性对应的 PropertyValue 的 value 是 org.springframework.beans.factory.config.TypedStringValue 类型(TypedStringValue: value [Cheque Wicket], target type [null]);company 属性对应的 PropertyValue 的 value 是 org.springframework.beans.factory.config.RuntimeBeanReference 类型(<macrohard>)。
- 接下来会创建一个帮助类 org.springframework.beans.factory.support.BeanDefinitionValueResolver,它的 resolveValueIfNecessary 方法可以将指定 BeanFactory 的指定 BeanDefinition 中的配置属性值转化为实际值。resolveValueIfNecessary 方法根据不同的值类型(PropertyValue 对象中 Object value 的实际类型)调用不同的处理流程解析属性值。
- 遍历 MutablePropertyValues propertyValues 中所有的 PropertyValue,通过 BeanDefinitionValueResolver 计算出转换后的实际值。对于 name 属性,它计算出的值就是 TypedStringValue 的 value:Cheque Wicket;对于 company 属性,它判断出类型是 RuntimeBeanReference,因此调用 BeanFactory 的 getBean 方法尝试获取 Company 的 singleton bean 实例,递归解析 bean reference 的依赖关系(见上图调用栈)。
- 当解析出所有属性实际值后,通过 org.springframework.beans.BeanWrapperImpl 的 setPropertyValues 方法为所有属性赋值。这部分代码原理很简单,对每个 PropertyValue,找出对应的 setter 方法,通过反射为属性赋值。但是实际代码很复杂,涉及到属性名的 token 化表示(例如 company.email 这种类型),以及如何确定 setter 方法等等细节问题,暂时不深入研究。
- 调用 initializeBean 方法初始化 bean 实例,包括响应各种 Aware 接口、处理 bean post processor 以及调用 init 方法等。
- 5~7:实例化 bean
- 8~12:装配 bean
- 13:初始化 bean
Spring IOC 源码简单分析 02 - Bean Reference的更多相关文章
- Spring IOC 源码简单分析 04 - bean的初始化
### 准备 ## 目标 了解 Spring 如何初始化 bean 实例 ##测试代码 gordon.study.spring.ioc.IOC04_Initialization.java publ ...
- Spring IOC 源码简单分析 03 - 循环引用
### 准备 ## 目标 了解 Spring 如何处理循环引用 ##测试代码 gordon.study.spring.ioc.IOC03_CircularReference.java ioc03. ...
- Spring IOC 源码简单分析 01 - BeanFactory
### 准备 ## 目标 了解 Spring IOC 的基础流程 ## 相关资源 Offical Doc:http://docs.spring.io/spring/docs/4.3.9.RELEASE ...
- Spring Ioc源码分析系列--Bean实例化过程(一)
Spring Ioc源码分析系列--Bean实例化过程(一) 前言 上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对 ...
- Spring Ioc源码分析系列--Bean实例化过程(二)
Spring Ioc源码分析系列--Bean实例化过程(二) 前言 上篇文章Spring Ioc源码分析系列--Bean实例化过程(一)简单分析了getBean()方法,还记得分析了什么吗?不记得了才 ...
- Spring Ioc源码分析系列--容器实例化Bean的四种方法
Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...
- Spring IOC 源码分析
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...
- spring IoC源码分析 (3)Resource解析
引自 spring IoC源码分析 (3)Resource解析 定义好了Resource之后,看到XmlFactoryBean的构造函数 public XmlBeanFactory(Resource ...
- Spring Ioc源码分析系列--Ioc的基础知识准备
Spring Ioc源码分析系列--Ioc的基础知识准备 本系列文章代码基于Spring Framework 5.2.x Ioc的概念 在Spring里,Ioc的定义为The IoC Containe ...
随机推荐
- oneThink的ArticleController控制,详看
本人新手小白,看下 onethink 的 ArticleController , 它里面写的方法,和一些自己以后改进的方向: <?php namespace Home\Controller; c ...
- 问答项目---金币经验奖励规则及网站配置写入config文件
具体步骤: 引入配置文件——>获取当前数组——>进行合并 public function edit(){ //引入 config.php配置文件 $file = APP_PATH.'Com ...
- oracle的认证方式
使用as sysdba是使用操作系统验证方式,不需要输入密码
- Oracle AWR之-enq: TX - allocate ITL entry
今天收到压力测试期间awr报告,测试人员要我看看数据库是否有可以优化的地方,数据库服务器配置信息:CPU:32*8,内存:480g 单实例数据库:oracle 11.2.0.4.具体分析过程如下: 可 ...
- Django - CBV、FBV
一.FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式. 二.CBV CBV(class base view ...
- PostgreSQL数据库的安装与PostGIS的安装(转)
原文:http://lovewinner.iteye.com/blog/1490915 安装postgresql sudo apt-get install postgresql-9.1 postgre ...
- yum whatprovides 查找哪个包可以提供缺失的文件
yum whatprovides 查找哪个包可以提供缺失的文件
- redhat 6.6 离线安装docker
本机环境:redhat6.6 uname -a Linux host- -.el6.x86_64 # SMP Tue Sep :: EDT x86_64 x86_64 x86_64 GNU/Linux ...
- python模块之shutil高级文件操作
简介 shutil模块提供了大量的文件的高级操作.特别针对文件拷贝和删除,主要功能为目录和文件操作以及压缩操作.对单个文件的操作也可参见os模块. 注意即便是更高级别的文件复制函数(shutil.co ...
- pxc wsrep_sst_method均配置为xtrabackup-v2报错
启动第二节点报错:WSREP_SST: [ERROR] Error while getting data from donor node: exit codes: 137 0 本来所有节点的wsrep ...