Spring Schema(2)

在前文《Spring Schema》中讲述了如何使用Spring Ext功能,但并未具体讲其内如原理。本篇进行一些补充。

要研究spring ext的实现原理就需要研究下解析xml文件生成相应的BeanDefination的过程了。下面的类图是与load BeanDefinition相关的主要的类:


Spring Schema(2)
 <!--[endif]-->

其中与Spring EXT相关的主要是NamespaceHandlerResolverResourceEntityResolver两个类。

         ResourceEntityResolver类由BeansDtdResolverPluggableSchemaResolver组成,用以在classpath下搜寻schemaDTD文件。而其中的PluggableSchemaResolver有一个schemaMappingsLocation属性其值为写死的META-INF/spring.schemas,这就找到了我们上面第四步里写的spring.schemas文件了。PluggableSchemaResolver把扫描到的schema存储在属性Map<String, String> schemaMappings中。除了在spring.schemas中自定义的schema外,PluggableSchemaResolver还会自动将spring默认的schema也扫面进来。例如:

 

{http://www.springframework.org/schema/lang/spring-lang-3.0.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd,
http://www.example.org/mydateformat/mydateformat.xsd=com/ronry/springtest/schema/mydateformat.xsd,
http://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd,
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd,
http://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd,
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd,
http://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd,
http://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd}

    (省略大部)

 

         类似,DefaultNamespaceHandlerResolver中也有一个属性handlerMappingsLocation其默认值为META-INF/spring.handlers,这也是我们第四步骤定义的文件。也同样有一个属性handlerMappings存储了namespace对应的handler,例如:

 

{http://www.example.org/mydateformat=com.ronry.springtest.schema.MyNamespaceHandler,
http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler,
http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler,
http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler,
http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler,
http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler,
http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler,
http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler}
 

 

这其中也已经包括了自定义的handlerspring默认的一些handler

         有了这些信息后,在解析bean定义的xml文件时,当遇到非默认命名空间(beans)的元素时,就按如下过程进行解析:

 

  1. 从元素中解析出nameSpaceUri;
  2. 根据nameSpaceUri,从DefaultNamespaceHandlerResolver中获取其对应的Handler加载Handler并 调用其init()方法;我们实现的MyNamespaceHandler在其inti()方法中注册了dataFormat标签的parser
  3. 调用handlerparser方法解析元素,具体又分为以下几步:

          1) 查找元素名对应的parser

          2)调用找到的parserparse()方法;

详细的解析过程如下图:

Spring Schema(2)
 <!--[endif]-->

         另外,还有一点想说的是BeanDefinitionParser的继承体系。自定的BeanDefinitionParser一般继承自AbstractSingleBeanDefinitionParser,其又继承自AbstractBeanDefinitionParser,如图:


Spring Schema(2)
 <!--[endif]-->

这个继承体系充分使用了模板方法的设计模式。调用时,会调用AbstractBeanDefinitionParserparse()方法,这也是BeanDefinitionParser接口定义的方法。parse()方法中调用parseInternal()方法,而该方法在AbstractBeanDefinitionParser只是个抽象方法,具体定义只有在AbstractSingleBeanDefinitionParser中才有。AbstractSingleBeanDefinitionParserparseInternal方法又会调用getBeanClass()doParse()方法,这两个在AbstractSingleBeanDefinitionParser也都是抽象方法(或者是return null的方法),需要在定义的Parser中覆盖。

你可能感兴趣的:(spring,AOP,xml,ejb,ext)