02-创建器

1. 构造工厂DefaultListableBeanFactory

XmlBeanFactory继承自DefaultListableBeanFactory,而DefaultListableBeanFactory是整个bean加载的核心部分,是默认实现,介绍下类图中的各个类的作用:

DefaultListableBeanFactory Class Diagram

  • (接口)AliasRegistry:定义对alias的简单增删改等操作;
  • (类)SimpleAliasRegistry:主要使用map作为alias的缓存,并对接口AliasRegistry进行实现;
  • (接口)SingletonBeanRegistry:定义对单例的注册及获取;
  • (接口)BeanFactory:定义获取bean及bean的各种属性;
  • (类)DefaultSingletonBeanRegistry:默认实现;
  • (接口)HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory定义的功能的基础上增加了对parentFactory的支持;
  • (接口)BeanDefinitionRegistry:定义对BeanDefinition的各种增删改操作;
  • (抽象类)FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry的基础上增加了对FactoryBean的特殊处理;
  • (接口)ConfigurableBeanFactory:提供配置Factory的各种方法;
  • (接口)ListableBeanFactory:根据各种条件获取bean的配置清单;
  • (抽象类)AbstractBeanFactory:综合了ConfigurableBeanFactory和FactoryBeanRegistrySupport的功能;
  • (接口)AutowireCapableBeanFactory:提供创建bean、自动注入、初始化以及应用bean的后处理器;
  • (抽象类)AbstractAutowireCapableBeanFactory:综合了AutowireCapableBeanFactory和AbstractBeanFactory的实现;
  • (接口)ConfigurableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等;
  • (类)DefaultListableBeanFactory:综合上面的类和接口,主要增加了对bean注册后的处理。

2. 配置文件读取和解析XmlBeanDefinitionReader

XmlBeanDefinitionReader Class Diagram
在使用XML配置式的Spring项目中,会用到这个XmlBeanDefinitionReader,包含了以下处理:

  1. 通过继承抽象类AbstractBeanDefinitionReader中的方法,使用ResourcesLoader将资源文件路径转换为对应的Resource文件;
  2. 通过DocumentLoader对Resource文件进行转换,讲Resource文件转换为Document文件;
  3. 通过实现接口BeanDefinitionDocumentReader的DefaultBeanDefinitionDocumentReader类对Document进行解析,并使用BeanDefinitionParserDelegete对Element进行解析。

3. 配置解析构造流程解析

在main方法中写下如下代码

1
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beansTest.xml"));

其执行逻辑为:

beanfactory seq

4. Resource封装

在java中不同资源文件有着URL作为抽象,但是不太实用,URL没有一些基本方法,比如检查是否存在,是否可读写,等,而spring则使用的自己封装的Resource来代表资源,类图如下

resource diagram

5. 实例化Bean

总体步骤其实很简单:

  1. 获取对XML文件的验证模式(DTD或者XSD);
  2. 加载XML文件,返回Document对象;
  3. 根据Document对象实例化bean。

    真正解析的方法为DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root)
    详细步骤如下:
    1、转换对于beaName。传入的name或者别名等,进行解析和转换,去除
    修饰符;
    2、尝试从缓存中加载单例;
    ps: 单例只会创建一次,spring会将ObjectFactory先创建到缓存中,再创建bean到缓存中;
    3、bean的实例化,如果从缓存中得到bean的原始状态,则需要对bean进行实例化;
    4、原型模式的依赖检查;
    5、检测parentBeanFactory;
    6、将存储文件的GenericBeanDefinition转换为RootBeanDefinition;
    7、寻找依赖;
    8、针对不同的scope进行bean的创建;
    9、类型转换;


作者 @Brady
2016年8月10日