Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx

上传人:b****7 文档编号:8800950 上传时间:2023-02-01 格式:DOCX 页数:20 大小:244.62KB
下载 相关 举报
Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx_第1页
第1页 / 共20页
Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx_第2页
第2页 / 共20页
Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx_第3页
第3页 / 共20页
Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx_第4页
第4页 / 共20页
Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx

《Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx》由会员分享,可在线阅读,更多相关《Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx(20页珍藏版)》请在冰豆网上搜索。

Spring32 中 Bean 定义之基于 XML 配置方式的源码解析.docx

Spring32中Bean定义之基于XML配置方式的源码解析

Spring3.2中Bean定义之基于XML配置方式的源码解析

看看新闻网>看引擎>IBM

Spring作为成熟的开源框架,已被开发人员广泛使用于日常开发中。

Spring自带的参考文档给开发人员提供了详细的使用介绍。

而作为开源框架的Spring源码,更为开发人员提供了许多优雅的设计思想和具体实现参考。

文章开始前,我们定义一个名词:

BeanDefinition:

即Bean定义,对应于Spring框架对一个Bean的定义,包括各种不同的属性参数,每个Bean都有一个或多个相关的BeanDefinition。

为了文章的可读性,在此我使用斜体表示,不将其翻译。

与Java程序中一个对象的执行大概经历定义、实例化和使用等阶段相似。

Spring容器中对象更加明确的经历了定义、实例化和使用等阶段:

∙对象定义:

Spring容器启动时,会根据开发人员对Bean(对象)的定义,统一解析这些Beans到 BeanDefinition容器(ConcurrentHashMapbeanDefinitionMap)中。

同时Spring也会解析一些容器启动所必须的和一些默认行为的Beans到 BeanDefinition容器中。

∙对象实例化:

Spring容器根据一定的规则,将beanDefinitionMap中的每个 BeanDefinition实例化为具体的Java对象,同时会将Singleton类型的对象缓存到bean容器(ConcurrentHashMapsingletonObjects)中。

∙对象使用:

前两步骤为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

org.springframework.web.context.ContextLoaderListener

这是一个典型的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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1