Spring容器启动过程

来源:互联网 发布:钢材贸易进销存软件 编辑:程序博客网 时间:2024/05/18 18:55

一、一切从手动启动IoC容器开始

[java] view plaincopy
  1. ClassPathResource resource = new ClassPathResource("bean.xml");  
  2. DefaultListableBeanFactory factory = new DefaultListableBeanFactory();  
  3. XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);  
  4. reader.loadBeanDefinitions(resource);  
 

第一行代码:ClassPathResource的作用是起到了资源定位的作用。通常情况下,Spring的配置信息使用文件来描述,通过这样一行代码,指明了需要加载的资源的位置,并且使用Spring能够理解的Resource接口的形式将资源描述出来。

第二行代码:DefaultListableBeanFactory是一个纯粹的IoC容器类,它是这个Spring的一个基础的IoC容器类,其他的一个IoC容器都是以这个类为基础进行扩展的。这样代码只是定义了一个IoC容器,它不具有任何其他的能力。

第三行代码:XmlBeanDefinitionReader是一个配置文件读取器。它实现了BeanDefinitionReader接口,它能够按照Spring配置文件,将其中的配置信息转换为spring内部可以识别的信息(BeanDefinition)。注意,在这里它的构造函数需要一个BeanDefinitionRegistry类型的参数,BeanDefinitionRegistry接口提供了一个回调函数,通过这个回调函数可以向IoC容器注册bean的定义信息。DefaultListableBeanFactory实现了这个接口。

第四行代码:调用loadeBeanDefinitions方法,通过给定的Resource资源,从中读取出spring的配置信息,转换为BeanDefinition,然后再调用BeanDefinitionRegistry的回调函数进行注册。

通过以上的四行代码,完成了spring容器的启动。

二、容器启动过程

1. 定位

在spring中,使用统一的资源表现方式Resource。根据不同的情况进行不同的选择。上述程序中,采用了编程式的资源定位方法,使用ClassPathResource定位位于classpath下的资源文件。

2. 加载

在加载这个过程中,主要工作是读取spring配置文件,解析配置文件中的内容,将这些信息转换成为Spring内容可以理解、使用的BeanDefinition。

3. 注册

加载过配置文件后,就将BeanDefinition信息注册到BeanDefinitionRegistry中,通常情况下Spring容器的实现类都实现这个接口。

 

三、资源加载实现

首先看一下XmlBeanDefinitionReader中的loadBeanDefinitions方法的实现


 

[java] view plaincopy
  1. public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {  
  2.         Assert.notNull(encodedResource, "EncodedResource must not be null");  
  3.         if (logger.isInfoEnabled()) {  
  4.             logger.info("Loading XML bean definitions from " + encodedResource.getResource());  
  5.         }  
  6.         Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();  
  7.         if (currentResources == null) {  
  8.             currentResources = new HashSet<EncodedResource>(4);  
  9.             this.resourcesCurrentlyBeingLoaded.set(currentResources);  
  10.         }  
  11.         if (!currentResources.add(encodedResource)) {  
  12.             throw new BeanDefinitionStoreException(  
  13.                     "Detected cyclic loading of " + encodedResource + " - check your import definitions!");  
  14.         }  
  15.         try {  
  16.             InputStream inputStream = encodedResource.getResource().getInputStream();  
  17.             try {  
  18.                 InputSource inputSource = new InputSource(inputStream);  
  19.                 if (encodedResource.getEncoding() != null) {  
  20.                     inputSource.setEncoding(encodedResource.getEncoding());  
  21.                 }  
  22.                 return doLoadBeanDefinitions(inputSource, encodedResource.getResource());  
  23.             }  
  24.             finally {  
  25.                 inputStream.close();  
  26.             }  
  27.         }  
  28.         catch (IOException ex) {  
  29.             throw new BeanDefinitionStoreException(  
  30.                     "IOException parsing XML document from " + encodedResource.getResource(), ex);  
  31.         }  
  32.         finally {  
  33.             currentResources.remove(encodedResource);  
  34.             if (currentResources.isEmpty()) {  
  35.                 this.resourcesCurrentlyBeingLoaded.set(null);  
  36.             }  
  37.         }  
  38.     }  

0 0
原创粉丝点击