zoukankan      html  css  js  c++  java
  • Spring-IOC学习-02 IOC容器初始化

    上次说到spring IOC 过程中的几个重要接口: Resource, BeanDefinition, BeanDefinitionRender ,BeanFactory, ApplicationContext 

    简单说了spring 的bean初始化流程:由 Resource接口的具体实现定位,读取资源文件。交给BeanfinintionRender进行bean的解析解析得到

     bean的描述对象BeanDefinition 。最后 BeanDefinitionRegister 会将已经等到的bean注册到 BeanFactory 容器中去完成bean的实例化

    过程。

    首先请看一个简单使用Spring的代码:

      

    不知道有没有这样使用过spring呢!这正是上面所说的spring在IOC初始化时的三个步骤。这样的获取是不是让你更明白IOC的初始化脉络?

    我们可以将 IOC容器初始化(bean的实例化) 过程分为 3 个部分 A:资源文件的定位  B:bean的解析,加载  C:bean的"注册"将解析后的BeanDefinition对象注册到BeanFactory

    中去.(该初始化过程是不包涵Bean 的依赖注入的 ,何时完成依赖呢? )  慢慢往下看吧......

    步骤1: BeanDefinition 资源文件的定位。

      上次说到spring 中有个重要的接口Resource 该接口负责Spring 资源文件的加载读取等操作.Reource根据不同的文件类型定位BeanDefinition。

    还记得FileSystemResource,ClassPathResource这俩个子类吗?他们都是 Resource 的具体实现。分别读取不同路径下的资源文件获取BeanDefinition

      查看上面的代码Spring  通过Resource 来定位BeanDefinition资源文件,然后在使用BeanDefinitionRender来将定位的资源文件处理后得到Spring要使用的BeanDefinition

    对象。因为我们使用的是单纯的容器仅仅是一个能装载 bean 的容器而已所以对于要使用什么样的Resource,什么样的BeanDefinitioRender都是由我们自己说了算的,所以这里就

    很灵活了但是,因为什么都要自己定制工作量就上来了。

      为什么会这么说?还记得ApplicationContext这个NB的接口吗?找个具体实现去看看吧为啥咱们在使用spring提供的这个接口的时候不用这写额外操作呢?因为别人办理做了呀看

    看别人怎么做的吧!

      

    怎么样很简单吧!!!!

    既然他已经得到了具体的Resource,那么FileSystemApplicationContext是怎样进行数据处理的,他是如何初始化BeanDefinition,BeanDefinitionRender的呢?查看该类并没有香瓜的代码,

    仅包含多个构造的重载方法,还有这个定位资源文件的方法 getResourceByPath(....);

    那么只有向他的父类找答案了! 在 AbstractRefreshableWebApplicationContext 中找到了答案! 看看FileSystemXmlApplicationContext的继承关系

     

      查看到AbstractRefreshableWebApplicationContext类的时候发了问题看一下refreshBeanFactory()方法吧!

     该方法创建了 DefaultListableBeanFactory beanFactory = createBeanFactory();  一个IOC 容器用来承载解析的BeanDefinition,容器有了那么BeanDefinition,和BeanDefinitionRender在哪里呢 ?

    回想一下文章开始的时候创建IOC的代码 创建好了工厂之后接着做了什么操作,ok现在是Resource,BeanFactory  接着就该BeanDefinitionRender( factory ) ;,还有他的loadBeanDefinitions(resource);

    就可以完成BeanDefinition的定位,载入了。这里依然是   loadBeanDefinitions(beanFactory);

    是不是和刚才我们自己获取很相近呢?  原来BeanDefinitionRender,BeanDefinition等都是在父类中执行的载入Bean 的操作当然这是合理的因为对于bean的定位来说不同的只是文件的路径也就是path用说不

    同而已,那么具体的路径交给具体的子类来实现就ok了,由子类自己来确定使用的资源。

    2:BeanDefinition的载入,解析过程

       FileSystemXmlApplicationContext.refresh();方法初始化BeanDefinition的入口方法。该方法会调用AbstractRefreshableApplicationContext中的refreshBeanFactory();方法完成 容器的创建 BeanDefinitionRender的初始化BeanDefinition载入等操作

    在refreshBeanFactory()方法中会调用 loadBeanDefinitions(beafactory); 该方法由根据不同的具体实现调用不同。此处调用的是  AbstractXmlApplicationContext中的 loadBeanDefinitions(beafactory);具体实现

    最后调用loadBeanDefinitions(XmlBeaDefinitionRender);来载入bean的操作,调用了一系列 loadBeanDefinitions()方法;虽然参数不一样但是不注意的话容易出错,具体解析xml的方法是 XmlBeaDefinitionRender中的doLoadBeanDefinitions(InputSource , Resource ) ;方法完成bean的载入,解析操作。

    spring 在何时将解析的bean信息封装成了自己的 BeanDefinition对象呢?

     这是在BeanDefinitionDocumentRender类中执行的通过 proccessBeanDefinitions( Elelment elt , BeanDefinitionParserDelegate delegate );

    最终处理beanDefinition是由BeanDefinitionParserDelegate对象来执行的 处理完成后会产生一个BeanDefinitionHolder对象该对象包涵了BeanDefinition信息还有一些额外信息比如别名等信息

    具体的标签解析是调用该类中的 parseBeanDefinitionElement(...) ,parseProppertyElements()....等parse方法进行的xml解析在该类中源码体现就不细说了。

    完成解析后就得到了DeanDefinitionHolder对象就得到了BeanDefintion的信息。就此bean的载入就完成了!

    3:将已经解析好的BeanDefinition注册到Ioc容器中去.

       这一步就是将上面解析得到的beanDefinition对象放到一个map中去.此时的beanDefinition已经可以使用了但是依赖关系尚未完成。

  • 相关阅读:
    C# Linq to XML
    C# StopWatch
    C# 深拷贝代码
    基础练习 完美的代价
    基础练习 矩形面积交
    基础练习 矩阵乘法 时间限制:1.0s 内存限制:512.0MB
    阶乘计算 高精度
    杨辉三角形 递归与非递归
    数的分解 时间限制:1000 ms | 内存限制:65535 KB 难度:1
    数列排序 sort qsort
  • 原文地址:https://www.cnblogs.com/javafengyi/p/3561772.html
Copyright © 2011-2022 走看看