spring—容器启动载入bean过程

来源:互联网 发布:周立功单片机怎么样 编辑:程序博客网 时间:2024/06/04 18:33

spring—容器启动载入bean过程

 此篇我们分析spring启动过程中代码大体的执行逻辑,在此,我们采用工程类的基类来进行分析,即对于以下几行代码执行过程中,spring后台所进行的处理。

客户端代码:

     ClassPathResource res = new ClassPathResource("applicationContext.xml");//第一行        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();//第二行        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);//第三行        int result = reader.loadBeanDefinitions(res);//第四行
第一行代码解析:

此行代码很简单,就是资源信息的定位,主要是确定资源文件位置和类加载器,如果用户不指定类加载器,则采用spring默认的类加载器,需要注意的是,这个resource会在载入bean的时候被封装成EncodedResource对象,这可以查看源代码

第二行:定义系统默认的beanFactory,对于这个工厂类,特别需要注意一个方法:public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition),这个方法会在对Bean进行解析完之后,把所有的bean对象通过此方法存入缓存,资源文件有多少个bean对象,那么就往这里注入多少个bean对象,这一步我会在下面详细的讲解;

第三行:把beanFactory注入bean的读取器里面,目的就是为了解析bean对象之后,利用第二步忘beanFactory里面注入

第四行:即对bean的加载过程,也是我们重点需要讲解的地方

1、XmlBeanDefinitionReader调用loadBeanDefinitions方法,最终定位到XmlBeanDefinitionReader的registerBeanDefinitions方法里面,在这个方法里面开始对bean进行解析,默认采用的DefaultBeanDefinitionDocumentReader的bean定义解析器,然后进入这个对象的registerBeanDefinitions方法,开始进行bean解析

2、在DefaultBeanDefinitionDocumentReader的registerBeanDefinitions(Document doc, XmlReaderContext readerContext)方法开始执行,需要注意的是,对于bean的解析也并不是在这个类里面完成的,是通过BeanDefinitionParserDelegate这个类来完成的,这个类才是真正进行XML文件或者其他资源文件解析的真正实现类,进入BeanDefinitionParserDelegate createHelper(XmlReaderContext readerContext, Element root) 这个方法,这个方法就是创建了这个真正解析bean的类,在创建这个bean解析对象之后,首先会设置bean的一些默认属性,这个是需要注意的,例如beans的default-init-method,以及default-destroy-method等等默认的属性设置,其实也就是XML文件里面的<beans>标签值进行设定,最终存放到DocumentDefaultsDefinition这个实体对象里面同时也注册了监听器

3、进入BeanDefinitionParserDelegate这个类的 parseBeanDefinitionElement(Element ele)方法,这个方法会传入每一个bean节点元素,这个方法会返回这个bean的BeanDefinitionHolder对象,查看这个类的parseBeanDefinitionElement(Element ele, BeanDefinition containingBean)方法,这个方法解析了这个bean里面的元素,通过

AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);得到这个bean的AbstractBeanDefinition 对象,这个也是关键的一点,即把每一个XML文件里面的bean元素最终封装成一个AbstractBeanDefinition 对象,通过对象里面的属性来存放XML文件的标签值,这里spring默认的是使用了GenericBeanDefinition类,即这个抽象类的实现类,当然我们可以扩展,如bean的构造函数,以及property元素都会存放到对象里面,创建这个对象之后,然后再创建

BeanDefinitionHolder对象,这个对象封装了beanName和这个AbstractBeanDefinition 的关联关系。

4、查看DefaultListableBeanFactory的processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)方法,即回到最初方法的入口,在这里会把返回的bean的holder对象通过BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());注入到beanFactory里面,这个也是很重要的一步。

到此为止bean的载入完成,在这个过程中必须要关注的是:

每一个bean都会被封装成一个AbstractBeanDefinition ,然后吧AbstractBeanDefinition 在存放到BeanDefinitionHolder里面,然后再把BeanDefinitionHolder存放到beanfactory的map里面,通过beanName和holder进行关联。

还有几个关键的类,需要注意即:DefaultBeanDefinitionDocumentReader和BeanDefinitionParserDelegate,XmlBeanDefinitionReader

所以综上所属,这个过程就是准备数据的过程,即把资源文件如XML文件里面的信息转换成对象数据结构进行存储



原文地址:http://m.blog.csdn.net/article/details?id=9261401

0 0