Spring-IOC学习-02 IOC容器初始化

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

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

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

过程。对象

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

  

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

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

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

 

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

  上次说到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已经可使用了可是依赖关系还没有完成。

相关文章
相关标签/搜索