java-Sping-IOC

1.IoC容器建立

BeanFactory是一个最基本的接口规范,其中包含getBean,containsBean,getAliases等方法

Spring提供了一个BeanFactory的基本实现,XmlBeanFactory同样的通过使用模板模式来得到对IOC容器的抽象- 
AbstractBeanFactory,DefaultListableBeanFactory这些抽象类为其提供模板服务。其中通过resource 接口来抽象bean定义数据,对Xml定义文件的解析通过委托给XmlBeanDefinitionReader来完成。下面的例子,简单的演示IOC容器的创建过程:

ClassPathResource res = new ClassPathResource("beans.xml");   
DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); 
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
  

  

这些代码演示了以下几个步骤:   
    1. 创建IOC配置文件的抽象资源     

  2. 创建一个BeanFactory  
    3. 把读取配置信息的BeanDefinitionReader,这里是XmlBeanDefinitionReader配置给BeanFactory  
    4. 从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成,这样完成整个载入bean定义的过程。我们的IoC容器就建立起来了。

   public class XmlBeanFactory extends DefaultListableBeanFactory {   
    //这里为容器定义了一个默认使用的bean定义读取器   
    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);   
    public XmlBeanFactory(Resource resource) throws BeansException {   
         this(resource, null);   
   }   
    //在初始化函数中使用读取器来对资源进行读取,得到bean定义信息。   
    public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {   
          super(parentBeanFactory);   
          this.reader.loadBeanDefinitions(resource);  
    }

备注( XmlBeanFactory[已废弃] 和 ApplicationContext 是两种IOC容器,其中实现的功能ApplicationContext 要多一点,BeanFactory往往不具备对资源定义的能力,而上下文可以自己完成资源定义)

2.ApplicationContext

仔细分析Spring BeanFactory的结构,我们来看看在BeanFactory基础上扩展出的ApplicationContext - 我们最常使用的上下文。除了具备BeanFactory的全部能力,上下文为应用程序又增添了许多便利:   
      * 可以支持不同的信息源,我们看到ApplicationContext扩展了MessageSource  

   * 访问资源 , 体现在对ResourceLoader和Resource的支持上面,这样我们可以从不同地方得到bean定义资源     

   * 支持应用事件,继承了接口ApplicationEventPublisher,这样在上下文中引入了事件机制而BeanFactory是没有的。

 

ApplicationContext提供IoC容器的主要接口,在其体系中有许多抽象子类比如AbstractApplicationContext为具体的BeanFactory的实现,比如FileSystemXmlApplicationContext和 ClassPathXmlApplicationContext提供上下文的模板,使得他们只需要关心具体的资源定
位问题。当应用程序代码实例化 FileSystemXmlApplicationContext的时候,得到IoC容器的一种具体表现 - ApplicationContext,从而应用程序通过ApplicationContext来管理对bean的操作。 BeanFactory 是一个接口,在实际应用中我们一般使用ApplicationContext来使用IOC容器,它们也是IOC容器展现给应用开发者的使用接口。对应用程序开发者来说,可以认为BeanFactory和ApplicationFactory在不同的使用层面上代表了SPRING提供的IOC容器服务。 下面我们具体看看通过FileSystemXmlApplicationContext是怎样建立起IOC容器的, 显而易见我们可以通过new来得到IoC容器:

ApplicationContext = new FileSystemXmlApplicationContext(xmlPath);

调用的是它初始化代码:

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)   throws BeansException {   
     super(parent);   
     this.configLocations = configLocations;   
     if (refresh) {   
       //这里是IoC容器的初始化过程,其初始化过程的大致步骤由AbstractApplicationContext来定义   
        refresh();   
    }   
}

refresh的模板在AbstractApplicationContext:

 

public void refresh() throws BeansException, IllegalStateException {  

    synchronized (this.startupShutdownMonitor) {    

       synchronized (this.activeMonitor) {        

         this.active = true;      

      }       
   // 这里需要子类来协助完成资源位置定义,bean载入和向IOC容器注册的过程         refreshBeanFactory();        

  ............  

 }  

  

这个方法包含了整个BeanFactory初始化的过程,对于特定的FileSystemXmlBeanFactory,我们看到定位资源位置由refreshBeanFactory()来实现:  
在AbstractXmlApplicationContext中定义了对资源的读取过程,默认由XmlBeanDefinitionReader来读取;

 

    * 初始化的入口在容器实现中的refresh()调用来完成  
    * 对bean 定义载入IOC容器使用的方法是loadBeanDefinition,其中的大致过程如下:通过ResourceLoader来完成资源文件位置的定位,DefaultResourceLoader是默认的实现,同时上下文本身就给出了ResourceLoader的实现,可以从类路径,文件系统, URL等方式来定为资源位置。如果是XmlBeanFactory作为IOC容器,那么需要为它指定bean定义的资源,也就是说bean定义文件时通过抽象成Resource来被IOC容器处理的,容器通过BeanDefinitionReader来完成定义信息的解析和Bean信息的注册,往往使用的是XmlBeanDefinitionReader来解析bean的xml定义文件 - 实际的处理过程是委托给BeanDefinitionParserDelegate来完成的,从而得到bean的定义信息,这些信息在Spring中使用BeanDefinition对象来表示 - 这个名字可以让我们想到
loadBeanDefinition,RegisterBeanDefinition这些相关的方法 - 他们都是为处理BeanDefinitin服务的,IoC容器解析得到BeanDefinition以后,需要把它在IOC容器中注册,这由IOC实现 BeanDefinitionRegistry接口来实现。注册过程就是在IOC容器内部维护的一个HashMap来保存得到的 BeanDefinition的过程。这个HashMap是IoC容器持有bean信息的场所,以后对bean的操作都是围绕这个HashMap来实现的。  
    * 然后我们就可以通过BeanFactory和ApplicationContext来享受到Spring IOC的服务了. 

 

 

  

posted on 2016-05-30 10:58  wonder2636  阅读(211)  评论(0编辑  收藏  举报

导航