Spring源码阅读和分析,分析Spring中最重要的BeanFactory的加载过程
本文流程都围绕以下代码展开1
2
3
4
5
6
7<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.example.methodlog.Student" />
</beans>
1 | public static void main(String[] args) { |
一、BeanFactory的加载过程
从new XmlBeanFactory(new ClassPathResource("bean.xml"));
这行代码开始入手,从这里开始进入Bean加载的分析,这行代码主要经历了三个步骤:
对XML进行
读取
验证包装成Document对Document进行
解析
,将每个bean封装成BeanDefinition
回调XmlBeanFactory注册BeanDefinition,将BeanDefinition放入到
beanDefinitionMap
中
bf.getBean("student")
这行代码是从BeanFactory中获取bean,但也是bean加载的主要步骤。bean的实例化、属性填充等就是在这里完成的。
调用栈 | 内容 | |
---|---|---|
读取 | XmlBeanFactory#XmlBeanFactory | 构造函数设置哪些接口不进行自动装配(添加到ignoredDependencyInterfaces) 委托给XmlBeanDefinitionReader来加载 |
XmlBeanDefinitionReader#loadBeanDefinitions | 将Resource包装成EncodedResource 记录正在加载的xml资源(添加到resourcesCurrentlyBeingLoaded) 将EncodedResource包装成InputSource | |
XmlBeanDefinitionReader#doLoadBeanDefinitions | 调用doLoadDocument和registerBeanDefinitions加载xml文件和注册bean | |
XmlBeanDefinitionReader# | 获取xml文件的DTD/XSD验证方法 | |
XmlBeanDefinitionReader#doLoadDocument | 委托给DefaultDocumentLoader将xml文件包装成Document | |
DefaultDocumentLoader#loadDocument | 简单加载xml文档并解析成Document | |
XmlBeanDefinitionReader#registerBeanDefinitions | 实例化DefaultBeanDefinitionDocumentReader并委托给它注册bean | |
解析 | DefaultBeanDefinitionDocumentReader# | 从Document中提取root |
DefaultBeanDefinitionDocumentReader# | 创建代理BeanDefinitionParserDelegate,处理profile属性 | |
DefaultBeanDefinitionDocumentReader# | 遍历所有标签,选择解析默认标签或自定义标签 | |
DefaultBeanDefinitionDocumentReader# | 对import、alias、bean、beans四种标签选择解析 | |
DefaultBeanDefinitionDocumentReader# | 将bean元素默认标签解析委托给BeanDefinitionParserDelegate 将bean元素自定义标签解析委托给BeanDefinitionParserDelegate 将bean的注册委托给BeanDefinitionReaderUtils | |
BeanDefinitionParserDelegate# | 提取元素的id和name属性 进一步解析其他所有属性并封装到GenericBeanDefinition实例中 如果没有为bean指定beanName,则生成一个beanName 将获取到的信息封装到BeanDefinitionHolder中 | |
BeanDefinitionParserDelegate# | 遍历子元素对子元素进行自定义标签解析 | |
注册 | BeanDefinitionReaderUtils#registerBeanDefinition | 回调XmlBeanFactory(DefaultListableBeanFactory)通过beanName和alias注册bean |
DefaultListableBeanFactory#registerBeanDefinition | 对bean进行校验 处理beanName已经注册的情况 将BeanDefinition放入beanDefinitionMap中 清除解析之前留下的beanName的缓存 | |
SimpleAliasRegistry#registerAlias | 通过别名注册BeanDefinition放到aliasMap中 |
调用栈 | 内容 | |
---|---|---|
加载 | AbstractBeanFactory#getBean | |
AbstractBeanFactory#doGetBean | 转换对应BeanName 尝试从缓存中加载单例,如果有进行后处理 原型模式的依赖检查 检查parentBeanFactory 将GenericBeanDefinition转换为RootBeanDefinition 寻找依赖dependsOn 针对不同类型的scope进行bean的创建 类型转换 | |
DefaultSingletonBeanRegistry#getSingleton | 从singletonObjects获取bean缓存实例 从earlySingletonObjects中获取bean缓存实例 从singletonFactories中获取bean缓存实例,移除singletonFactories,加入earlySingletonObjects | |
AbstractBeanFactory#getObjectForBeanInstance | 处理FactoryBean的情况 | |
DefaultSingletonBeanRegistry#getSingleton | 缓存中不存在已加载的单例bean,开始bean的加载 添加singletonsCurrentlyInCreation标记bean正在加载 回调ObjectFactory创建bean 移除singletonsCurrentlyInCreation中bean的正在加载状态 将实例完的bean放入singletonObjects,添加registeredSingletons 并移除singletonFactories和earlySingletonObjects | |
AbstractAutowireCapableBeanFactory# | 根据设置的class或根据className解析Class 对override属性进行标记和验证(lookup-method、replace-method) InstantiationAwareBeanPostProcessor后处理器,是否初始化前的短路操作(AOP) 创建bean | |
AbstractAutowireCapableBeanFactory# | 实例化Bean,将BeanDefinition转换为BeanWrapper MergedBeanDefinitionPostProcessor的应用(@Autowired/@Resource的预解析) 提前曝光自身,添加到singletonFactories和registeredSingletons,移除earlySingletonObjects 属性填充,将所有属性填充到bean的实例中 调用初始化方法(init-method) 循环依赖检查 注册DisposableBean(destroy-method) | |
AbstractAutowireCapableBeanFactory# | 根据有参构造器实例化对象 | |
AbstractAutowireCapableBeanFactory# | 根据无参构造器实例化对象 | |
AbstractAutowireCapableBeanFactory# | 应用MergedBeanDefinitionPostProcessor后处理器(@Autowired/@Resource的预解析) | |
DefaultSingletonBeanRegistry# | 提前曝光自身,解决循环依赖 添加到singletonFactories和registeredSingletons,移除earlySingletonObjects | |
AbstractAutowireCapableBeanFactory# | InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation控制是否进行属性填充 根据注入类型(byNames/byType),提取需要注入的属性 InstantiationAwareBeanPostProcessor.postProcessPropertyValues属性填充前的再处理(@Autowired/@Resource的属性值填充) 将所有属性填充到BeanWrapper中 | |
AbstractAutowireCapableBeanFactory# | 激活Aware方法(注入BeanFactory等) postProcessBeforeInitialization 调用init方法 postProcessAfterInitialization |
二、BeanFactory的加载流程图
2.1 加载单例的大体流程图
单例的获取主要经过了4步:
1、读取xml文件,得到Docment类
2、解析Docment,将bean解析成BeanDefinition
3、注册BeanDefinition,将BeanDefinition放入beanDefinitionMap中
4、根据beanName从beanDefinitionMap取出BeanDefinition,然后经过加载获得单例
2.2 加载单例的大体时序图
2.3 核心类图和类功能
SimpleAliasRegistry:主要使用map作为alias的缓存,实现对alias的增删改等操作
DefaultSingletonBeanRegistry:对单例的注册及获取
FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry的基础上增加了对FactoryBean的特殊处理功能
AbstractBeanFactory:提供单例缓存、bean合并和bean销毁、管理bean工厂层次结构
AbstractAutowireCapableBeanFactory:提供Bean的创建、属性填充、自动注入、初始化、解决循环依赖等功能
DefaultListableBeanFactory:在使用bean之前注册bean
BeanDefinition:配置文件
RootBeanDefinition:父
ChildBeanDefinition:子
GenericBeanDefinition:2.5版本后新加入的bean文件配置属性定义类,是一站式服务类