`

spring 源码分析--IOC容器初始化五

阅读更多

上面完成了对资源的定位工作,接下去就是解析资源的内容了,接着第四节的第一个函数说,这一节主要完成将xml文件解析为DOM对象,函数的职责很单一。

 

 

  1.2.2.1.1.3.1.1.3 loadBeanDefinitions(EncodedResource encodedResource): 方法定义在 XmlBeanDefinitionReader 类中,用以装载以 xml 格式定义的 bean

====================================================================

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());

    }

// 使用 ThreadLocal 解决多线程问题。

Set currentResources = (Set ) this . resourcesCurrentlyBeingLoaded .get();

    if (currentResources == null ) {

       currentResources = new HashSet (4);

       this . resourcesCurrentlyBeingLoaded .set(currentResources) ;

    }

// 放置资源。

    if (!currentResources.add(encodedResource) ) {

       throw new BeanDefinitionStoreException(

       "Detected recursive loading of " + encodedResource + " - check your import definitions!" );

    }

    try {

    // 这里通过 Resource 得到 InputStream IO

       InputStream inputStream = encodedResource.getResource().getInputStream();

       try {

       // InputStream 中得到 XML 的解析源  

           InputSource inputSource = new InputSource(inputStream);

           if (encodedResource.getEncoding() != null ) {

               inputSource.setEncoding(encodedResource.getEncoding());

           }

       // 这里是具体的解析和注册过程

           return doLoadBeanDefinitions(inputSource, encodedResource.getResource()) ;

           }

           finally {

           // 关闭从 Resource 中得到的 IO  

              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 ) ;

           }

       }

    }

====================================================================

然后进入到具体的解析过程,实际真正从 xml 中装载 bean 的地方:即函数;

(从上面的过程可以知道,接下去的工作都会在下面的函数里完成,所以先做一个假设:2=1.2.2.1.1.3.1.1.3.1)

 

2. doLoadBeanDefinitions(inputSource, encodedResource.getResource())

该函数定义在 XmlBeanDefinitionReader

====================================================================

protected int doLoadBeanDefinitions (InputSource inputSource, Resource resource)

throws BeanDefinitionStoreException {

    try {

    // 通过解析得到 DOM ,然后完成 bean IOC 容器中的注册

       int validationMode = getValidationModeForResource(resource);

       Document doc = this . documentLoader .loadDocument(

              inputSource, getEntityResolver(), this . errorHandler , validationMode, isNamespaceAware());

       return registerBeanDefinitions(doc, resource) ;

    } catch (BeanDefinitionStoreException ex) {

           throw ex;

    } catch (SAXParseException ex) {

              throw new XmlBeanDefinitionStoreException(resource.getDescription(),

                     "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid" , ex);

    } catch (SAXException ex) {

              throw new XmlBeanDefinitionStoreException(resource.getDescription(),

                  "XML document from " + resource + " is invalid" , ex);

    } catch (ParserConfigurationException ex) {

              throw new BeanDefinitionStoreException(resource.getDescription(),

                     "Parser configuration exception parsing XML from " + resource, ex);

    } catch (IOException ex) {

              throw new BeanDefinitionStoreException(resource.getDescription(),

             "IOException parsing XML document from " + resource, ex);

    } catch (Throwable ex) {

           throw new BeanDefinitionStoreException(resource.getDescription(),

                  "Unexpected exception parsing XML document from " + resource, ex);

    }

}

====================================================================

 

 

2.1 registerBeanDefinitions(doc, resource) 我们看到先把定义文件解析为 DOM 对象,然后进行具体的注册过程:

====================================================================

public int registerBeanDefinitions (Document doc, Resource resource) throws BeanDefinitionStoreException {

// Support old XmlBeanDefinitionParser SPI for backwards-compatibility.

// 这里定义解析器,使用 XmlBeanDefinitionParser 来解析 xml 方式的 bean 定义文件

// 现在的版本不用这个解析器了,使用的是 XmlBeanDefinitionReader 

       if ( this . parserClass != null ) {

           XmlBeanDefinitionParser parser =

(XmlBeanDefinitionParser ) BeanUtils.instantiateClass ( this . parserClass );

           return parser.registerBeanDefinitions( this , doc, resource) ;

       }

// Read document based on new BeanDefinitionDocumentReader SPI.

// 具体的注册过程 , 首先得到 DefaultBeanDefinitionDocumentReader , 来处理 xml

// bean 定义文件

BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();

// 得到当前容器中 bean 的数量,由 前面 可知,这里的 Registry 实际上是一个 // DefaultListableBeanFactory 里实际上是得到 DefaultListableBeanFactory // 类中字段 beanDefinitionMap 的大小。

       int countBefore = getRegistry().getBeanDefinitionCount();

documentReader.registerBeanDefinitions(doc, createReaderContext(resource)) ;

       return getRegistry().getBeanDefinitionCount() - countBefore;

    }

====================================================================

 

 

 

²2.1.1 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)): 在类

DefaultBeanDefinitionDocumentReader 中定义

====================================================================

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {

    this . readerContext = readerContext;

    logger .debug( "Loading bean definitions" );

    Element root = doc.getDocumentElement();

    BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);

// 允许子类继承预处理 xml ,默认实现为空。

preProcessXml(root);

    parseBeanDefinitions(root, delegate);

// 允许子类继承进一步处理 xml ,默认实现为空。

    postProcessXml(root);

    }

====================================================================

 

 

本站支持 pay for your wishes

1
3
分享到:
评论

相关推荐

    Spring源码分析_Spring_IOC

    ### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...

    Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程.doc

    Spring 框架系列(7)- Spring IOC 实现原理详解之 IOC 初始化流程 本文将详细解释 Spring 框架中的 IOC...IOC 容器的初始化流程是 Spring 框架中的关键部分,用于将资源配置文件中的信息加载到 IOC 容器中。

    Spring源码解析4章150页+Spring3.2.4中文注释源码

    3、源码分析-IOC容器的初始化 4、源码分析-IOC容器的依赖注入 5、源码分析-IOC容器的高级特性 三阶段 Spring AOP的涉及原理及具体实践 SpringJDBC的涉及原理及二次开发 SpringMVC框架设计原理及手写实现 四阶段 ...

    Spring IOC容器实现分析.pdf 下载

    《Spring IOC容器实现分析》 在Java开发领域,Spring框架无疑是使用最为广泛的轻量级框架之一,其中的核心组件就是IOC(Inversion of Control)容器。本文将深入剖析Spring的IOC容器,理解其工作原理和重要功能,以...

    spring源码解读-地址.txt

    根据提供的文件信息,本次解读将围绕Spring框架的核心概念与源码分析进行展开。Spring框架作为Java企业级开发中不可或缺的一部分,其源码的学习对于深入理解框架机制、提高开发效率具有重要意义。下面,我们将从以下...

    官方原版源码spring-framework-5.1.13.RELEASE.zip

    通过分析BeanFactory,我们可以了解对象的创建、初始化和依赖注入过程。 - **AOP**:面向切面编程允许我们定义横切关注点,如日志记录、事务管理,然后将其模块化为可重用的组件。 - **Data Access/...

    Spring IoC源码深度剖析开源架构源码2021.pdf

    文档可能将深入探讨Spring IoC容器初始化、Bean生命周期管理、依赖注入等关键概念,并以2021年的开源版本为背景进行分析。 从提供的部分文档内容来看,我们可以提炼出以下几个知识点: 1. **BeanFactory与...

    官方原版源码 spring-framework-5.1.15.RELEASE.zip

    Spring Core负责基础的IoC(Inversion of Control)容器,Spring Beans则实现了Bean的生命周期管理和配置,Spring Context则是基于Core之上构建的,提供了一个应用上下文,可以管理Bean并与其他Spring模块集成。...

    【框架源码篇 01】Spring源码-手写IOC

    5. **Bean管理**:最后,容器会管理Bean的生命周期,包括初始化、使用和销毁。 在实际开发中,Spring使用了更加高效和灵活的方式来实现这些功能,比如使用`ApplicationContext`接口作为IOC容器的入口,以及`...

    官方原版源码 spring-framework-5.2.9.RELEASE.zip

    1. **ApplicationContext**:这是Spring的核心接口,负责初始化、加载配置文件,管理Bean的生命周期。源码中可以看到它是如何解析XML或Java配置,创建并管理Bean的。 2. **BeanFactory**:作为ApplicationContext的...

    官方原版源码spring-framework-5.1.0.RELEASE.zip

    2. **Spring Beans**:实现了IoC容器,通过XML或注解方式配置bean,并负责bean的初始化、装配和销毁。 3. **Spring AOP**:面向切面编程模块,允许定义方法拦截器和切入点,实现代码的解耦和模块化。 4. **Spring ...

    官方原版源码spring-framework-5.0.13.RELEASE.zip

    1. **初始化流程**:从`org.springframework.context.support.ClassPathXmlApplicationContext`或`org.springframework.web.context.ContextLoader`开始,理解如何加载配置并创建Bean定义。 2. **依赖注入**:研究`...

    spring-framework-2.5-rc2-with-dependencies\spring-framework-2.5-rc2\spring-framework-2.5-rc2源代码

    通过阅读和学习这些源码,开发者可以了解到Spring如何实现IoC容器、AOP代理、事件机制、任务调度等多个关键功能。同时,这也有助于开发者更好地理解和使用Spring提供的API,以及在实际项目中如何定制和扩展Spring。 ...

    spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar

    在深入探讨Spring框架的核心组件和工作...在分析或运行Spring源码时,确保正确引入这两个库是确保项目正常运行的关键。通过深入了解这些工具库,开发者可以更好地理解和运用Spring框架,从而提高开发效率和应用性能。

    Spring2.5.6源代码分析(一):IOC容器

    IoC容器是Spring框架的心脏,它负责管理对象的生命周期和依赖关系,使得开发者能够实现松耦合和高可测试性的应用程序。 首先,我们来理解什么是IoC。IoC,也被称为依赖注入(Dependency Injection),是一种设计...

    spring-framework-5.3.29.tar.gz

    通过XML配置文件或Java注解,我们可以定义bean的创建、初始化和销毁过程,实现依赖注入,从而降低代码的耦合度。 2. AOP:Spring的AOP模块允许开发者定义横切关注点,如日志记录、事务管理等,将这些关注点与业务...

    Spring 5.2.9的IOC核心jar包

    通过配置文件或者注解,开发者可以定义对象及其依赖关系,Spring容器会自动管理这些对象的生命周期,包括实例化、初始化、装配和销毁。 **Bean** 在Spring中,业务逻辑的组件被称为Bean。Bean是Spring容器管理的...

    Spring IOC容器实现分析

    本文将基于Spring 2.0版本的源码,深入分析Spring IOC容器的内部实现机制,帮助读者更好地理解和使用这一强大的工具。 #### 二、核心概念与术语 在深入探讨Spring IOC容器之前,我们首先需要了解几个核心的概念: ...

    coco-spring-ioc

    《简易Spring-ioc详解》 在Java开发领域,Spring框架以其强大的功能和广泛的应用而备受开发者喜爱。...此外,掌握这些核心概念后,无论是使用Spring框架还是其他类似的IoC容器,都将更加得心应手。

Global site tag (gtag.js) - Google Analytics