Spring容器启动过程

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

    ClassPathResource resource = new ClassPathResource("bean.xml");  
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();  
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);  
    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方法的实现

    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {  
            Assert.notNull(encodedResource, "EncodedResource must not be null");  
            if (logger.isInfoEnabled()) {  
                logger.info("Loading XML bean definitions from " + encodedResource.getResource());  
            }  
            Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();  
            if (currentResources == null) {  
                currentResources = new HashSet<EncodedResource>(4);  
                this.resourcesCurrentlyBeingLoaded.set(currentResources);  
            }  
            if (!currentResources.add(encodedResource)) {  
                throw new BeanDefinitionStoreException(  
                        "Detected cyclic loading of " + encodedResource + " - check your import definitions!");  
            }  
            try {  
                InputStream inputStream = encodedResource.getResource().getInputStream();  
                try {  
                    InputSource inputSource = new InputSource(inputStream);  
                    if (encodedResource.getEncoding() != null) {  
                        inputSource.setEncoding(encodedResource.getEncoding());  
                    }  
                    return doLoadBeanDefinitions(inputSource, encodedResource.getResource());  
                }  
                finally {  
                    inputStream.close();  
                }  
            }  
            catch (IOException ex) {  
                throw new BeanDefinitionStoreException(  
                        "IOException parsing XML document from " + encodedResource.getResource(), ex);  
            }  
            finally {  
                currentResources.remove(encodedResource);  
                if (currentResources.isEmpty()) {  
                    this.resourcesCurrentlyBeingLoaded.set(null);  
                }  
            }  
        }  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值