Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx
- 文档编号:8800950
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:20
- 大小:244.62KB
Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx
《Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx》由会员分享,可在线阅读,更多相关《Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx(20页珍藏版)》请在冰豆网上搜索。
Spring32中Bean定义之基于XML配置方式的源码解析
Spring3.2中Bean定义之基于XML配置方式的源码解析
看看新闻网>看引擎>IBM
Spring作为成熟的开源框架,已被开发人员广泛使用于日常开发中。
Spring自带的参考文档给开发人员提供了详细的使用介绍。
而作为开源框架的Spring源码,更为开发人员提供了许多优雅的设计思想和具体实现参考。
文章开始前,我们定义一个名词:
BeanDefinition:
即Bean定义,对应于Spring框架对一个Bean的定义,包括各种不同的属性参数,每个Bean都有一个或多个相关的BeanDefinition。
为了文章的可读性,在此我使用斜体表示,不将其翻译。
与Java程序中一个对象的执行大概经历定义、实例化和使用等阶段相似。
Spring容器中对象更加明确的经历了定义、实例化和使用等阶段:
∙对象定义:
Spring容器启动时,会根据开发人员对Bean(对象)的定义,统一解析这些Beans到 BeanDefinition容器(ConcurrentHashMap
同时Spring也会解析一些容器启动所必须的和一些默认行为的Beans到 BeanDefinition容器中。
∙对象实例化:
Spring容器根据一定的规则,将beanDefinitionMap中的每个 BeanDefinition实例化为具体的Java对象,同时会将Singleton类型的对象缓存到bean容器(ConcurrentHashMap
∙对象使用:
前两步骤为Spring容器启动时执行,该步骤为应用程序在执行相关业务逻辑时,会到Spring容器中找出(Single类型)或者实例化(如Prototype类型)相关对象,供业务逻辑使用。
本文主要分析SpringIoC容器解析基于XML配置方式的 BeanDefinition的源码实现,给开发人员提供一个知其然,并知其所以然的途径。
Spring简介及BeanDefinition配置方式
Spring是2003年兴起的一个轻量级Java开发框架,经过十多年的不断积累和演进,如今已成为功能相同或相似解决方案最为流行的开源框架。
SpringIoC改变了传统的对象定义和使用方式,SpringAOP为开发人员提供了一种简单但功能强大的面向切面的编程方式,SpringMVC简化了WEB开发的流程,使得开发人员更能专注于业务逻辑代码的开发。
Spring可以用在各种类型的应用开发上。
对于WebProject,开发人员只要在web.xml加入下列代码,并将相关Spring依赖文件引入就可以在开发中使用Spring。
清单1.Web.xml引入Spring
这是一个典型的ServletContextListener,Servlet容器(如Tomcat等)在启动时会找到ContextLoaderListener并执行其contextInitialized(ServletContextEventevent)方法。
从这里开始,Spring将会进行 BeanDefinition的解析、BeanProcessors设置和处理、Beans实例化等工作。
从而将程序会用到的Java对象定义并根据该定义创建好,提供给开发人员去使用。
这里Spring首先需要处理的就是Bean的定义。
经过不断的发展和演化,Bean的定义方式有:
∙基于XML文件的配置方式。
∙基于Annotation的配置方式。
∙基于JavaCode的配置方式。
∙用户自定义的配置方式。
回页首
基于XML配置BeanDefinition的源码解读
XML配置rootWebApplicationContext
前文介绍,Servlet容器启动时如果web.xml配置了ContextLoaderListener,则会调用该对象的初始化方法。
根据Java语法规定,ContextLoaderListener的父类ContextLoader有一段static的代码会更早被执行,这段代码配置了XML默认使用的Context为org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext 根据该定义,如果开发人员没有从web.xml指定contextClass参数,则默认使用XmlWebApplicationContext作为rootWebApplicationContext工具类。
XML命名空间及XML配置文件解析
Spring采用XML命名空间的方式,为框架的扩展提供了极大的方便。
清单2.XML配置文件的命名空间定义
xmlversion="1.0"encoding="UTF-8"?
>
//www.springframework.org/schema/beans" xmlns: xsi="http: //www.w3.org/2001/XMLSchema-instance" xmlns: context="http: //www.springframework.org/schema/context" xsi: schemaLocation="http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-3.2.xsd http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans-3.2.xsd> 清单2展示在XML配置文件中引入命名空间的配置范例。 图1.XML命名空间及其handler定义(查看大图) 展开Spring的依赖jar文件,可以看到Spring各个模块对应的jar包都包含一个META-INF目录,如果使用了命名空间,则该目录包含了spring.schemas和spring.handlers两个文件,如图1所示。 然后Spring代码通过Properties工具类扫描project的classpath以及其使用的所有依赖包中META-INF目录来得到对应参数值供后续使用。 PropertiesLoaderUtils.loadAllProperties(“META-INF/spring.schemas”, this.classLoader); PropertiesLoaderUtils.loadAllProperties(“META-INF/spring.handlers”, this.classLoader); 清单3.JAXP方式解析XML文件为Java对象 protectedintdoLoadBeanDefinitions(InputSourceinputSource,Resourceresource) throwsBeanDefinitionStoreException{ try{ intvalidationMode=getValidationModeForResource(resource); //使用JAXP方式,将XML配置文件解析为Java对象。 Documentdoc=this.documentLoader.loadDocument(inputSource, getEntityResolver(),this.errorHandler, validationMode,isNamespaceAware()); returnregisterBeanDefinitions(doc,resource); } 清单3表示Spring源码会创建一些必须的属性或对象,读入配置文件(通常为XML文件),使用JAXP方式将XML元素转换为Java对象(Documentdoc)。 这样Spring对XML配置文件的处理,都可以看作对Java对象的处理。 图2.XML配置文件解析预处理顺序图(查看大图) 图2展示Spring框架如何根据XML配置文件,创建辅助类,从而实现对用户自定义的Bean解析的过程。 详细分析如下: 1.Spring容器在Servlet容器启动后,经过一系列的配置和处理到达如下步骤; 2.调用AbstractApplicationContext对象的refreshBeanFactory();方法。 在这个方法里,将会完成后面所有解析处理。 3.步骤2首先创建一个DefaultListableBeanFactory对象,该对象的类图如图3 所示。 这是Spring框架的核心类,Spring的Bean解析和实例化以及后续的使用都跟该类有非常密切的关系。 从类图右上角部分可知,该类实现了BeanFactory及其几个子接口,这里定义了DefaultListableBeanFactory具有的业务接口(如getBean(…)等)。 而图的左边的类图展示了DefaultListableBeanFactory类的具体业务实现。 图3.DefaultListableBeanFactory类图(查看大图) 4.调用XmlWebApplicationContext对象的loadBeanDefinitions方法,其参数为步骤3创建的beanFactory.这个方法定义了XmlBeanDefinitionReader对象beanDefinitionReader并设置了其属性(如DocumentLoader,EntityResolver等)用于XML文件的解析。 XmlWebApplicationContext对象还负责设置XML配置文件名,默认为/WEB-INF/applicationContext.xml。 如果是开发人员定义的配置文件,则可能为多个。 5.该步骤根据步骤4定义的配置文件名(一个或多个),调用beanDefinitionReader的loadBeanDefinitions方法循环解析每个配置文件,传入的参数为配置文件名。 6.步骤5的beanDefinitionReader会通过JAXP方式解析XML配置文件为Document对象doc,Spring框架对XML配置文件的处理即转化为对Java对象(Document)的处理。 7.步骤4中beanDefinitionReader会创建两个对象: DefaultBeanDefinitionDocumentReader对象documentReader和XmlReaderContext对象readerContext.DefaultBeanDefinitionDocumentReader的属性如清单4: 清单4.DocumentReader属性清单 publicclassDefaultBeanDefinitionDocumentReader implementsBeanDefinitionDocumentReader{ publicstaticfinalStringBEAN_ELEMENT=BeanDefinitionParserDelegate.BEAN_ELEMENT; publicstaticfinalStringNESTED_BEANS_ELEMENT="beans"; publicstaticfinalStringALIAS_ELEMENT="alias"; publicstaticfinalStringNAME_ATTRIBUTE="name"; publicstaticfinalStringALIAS_ATTRIBUTE="alias"; publicstaticfinalStringIMPORT_ELEMENT="import"; publicstaticfinalStringRESOURCE_ATTRIBUTE="resource"; /**@seeorg.springframework.context.annotation.Profile*/ publicstaticfinalStringPROFILE_ATTRIBUTE="profile"; protectedfinalLoglogger=LogFactory.getLog(getClass()); privateXmlReaderContextreaderContext; privateEnvironmentenvironment; privateBeanDefinitionParserDelegatedelegate; 从上述清单以及XML配置对比可知,该对象定义了 其第 一个属性即为每个Bean的配置元素 readerContext对象定义了一些如resource,eventListener和 namespaceHandlerResolver等上下文信息。 通过这些属性,Spring框架获得需要解析的XML文件,命名空间解析辅助类以及特定事件的监听器等。 8.以步骤6和7创建的doc和readerContext为参数,调用documentReader对象的registerBeanDefinitions方法。 9.步骤8会创建一个工具类BeanDefinitionParserDelegate,其部分属性如清单5。 清单5.BeanDefinitionParserDelegate属性清单 publicclassBeanDefinitionParserDelegate{ ... publicstaticfinalStringTRUE_VALUE="true"; publicstaticfinalStringFALSE_VALUE="false"; publicstaticfinalStringDEFAULT_VALUE="default"; publicstaticfinalStringDESCRIPTION_ELEMENT="description"; publicstaticfinalStringAUTOWIRE_NO_VALUE="no"; publicstaticfinalStringAUTOWIRE_BY_NAME_VALUE="byName"; publicstaticfinalStringAUTOWIRE_BY_TYPE_VALUE="byType"; publicstaticfinalStringAUTOWIRE_CONSTRUCTOR_VALUE="constructor"; publicstaticfinalStringAUTOWIRE_AUTODETECT_VALUE="autodetect"; publicstaticfinalStringDEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE="all"; publicstaticfinalStringDEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE="simple"; publicstaticfinalStringDEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE="objects"; publicstaticfinalStringNAME_ATTRIBUTE="name"; publicstaticfinalStringBEAN_ELEMENT="bean"; publicstaticfinalStringMETA_ELEMENT="meta"; publicstaticfinalStringID_ATTRIBUTE="id"; publicstaticfinalStringPARENT_ATTRIBUTE="parent"; publicstaticfinalStringCLASS_ATTRIBUTE="class"; publicstaticfinalStringABSTRACT_ATTRIBUTE="abstract"; publicstaticfinalStringSCOPE_ATTRIBUTE="scope"; publicstaticfinalStringSINGLETON_ATTRIBUTE="singleton"; publicstaticfinalStringLAZY_INIT_ATTRIBUTE="lazy-init"; publicstaticfinalStringAUTOWIRE_ATTRIBUTE="autowire"; publicstaticfinalStringAUTOWIRE_CANDIDATE_ATTRIBUTE="autowire-candidate"; publicstaticfinalStringPRIMARY_ATTRIBUTE="primary"; publicstaticfinalStringDEPENDENCY_CHECK_ATTRIBUTE="dependency-check"; publicstaticfinalStringDEPENDS_ON_ATTRIBUTE="depends-on"; publicstaticfinalStringINIT_METHOD_ATTRIBUTE="init-method"; publicstaticfinalStringDESTROY_METHOD_ATTRIBUTE="destroy-method"; publicstaticfinalStringFACTORY_METHOD_ATTRIBUTE="factory-method"; publicstaticfinalStringFACTORY_BEAN_ATTRIBUTE="factory-bean"; publicstaticfinalStringCONSTRUCTOR_ARG_ELEMENT="constructor-arg"; publicstaticfinalStringINDEX_ATTRIBUTE="index"; publicstaticfinalStringTYPE_ATTRIBUTE="type"; publicstaticfinalStringVALUE_TYPE_ATTRIBUTE="value-type"; publicstaticfinalStringKEY_TYPE_ATTRIBUTE="key-type"; publicstaticfinalStringPROPERTY_ELEMENT="property"; publicstaticfinalStringREF_ATTRIBUTE="ref"; publicstaticfinalStringVALUE_ATTRIBUTE="value"; publicstaticfinalStringLOOKUP_METHOD_ELEMENT="lookup-method"; publicstaticfinalStringREPLACED_METHOD_ELEMENT="replaced-method"; publicstaticfinalStringREPLACER_ATTRIBUTE="replacer"; publicstaticfinalStringARG_TYPE_ELEMENT="arg-type"; publicstaticfinalStringREF_ELEMENT="ref"; ... publicstaticfinalStringDEFAULT_LAZY_INIT_ATTRIBUTE="default-lazy-init"; publicstaticfinalStringDEFAULT_MERGE_ATTRIBUTE="default-merge"; publicstaticfinalStringDEFAULT_AUTOWIRE_ATTRIBUTE="default-autowire"; publicstaticfinalStringDEFAULT_DEPENDENCY_CHECK_ATTRIBUTE= "default-dependency-check"; publicstaticfinalStringDEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE= "default-autowire-candidates"; publicstaticfinalStringDEFAULT_INIT_METHOD_ATTRIBUTE= "default-init-method"; publicstaticfinalStringDEFAULT_DESTROY_METHOD_ATTRIBUTE= "default-destroy-method"; ... privatefinalXmlR
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Spring32 Bean 定义之基于 XML 配置方式的源码解析 定义 基于 配置 方式 源码 解析