spring namespaceHandler

    xiaoxiao2021-03-25  116

    首先声明

    Spring 2.0已经把aop、transaction/tx、jndi和Web MVC等等配置放入单独的namespace中(从spring.jar!/META-INF/spring.handlers中就能找到)。

    老式的bean定义虽然可以适合绝大部分的配置工作,但是在一些特殊领域难免显得冗长拖沓,这些领域往往有自己的领域定义,继续沿用老式的bean定义除了会把人搞晕以外倒也没有其他恶行,这种情景之下,使用自己的namespace然后通过自定义的NamespaceHandler去注册bean可以使得编写XML配置的时候更加符合特定领域的语义要求,增强XML文件的可读性。

    代码均摘抄自spring-reference.pdf

    分为四步:

    第一: Authoringan XML schema to describe your custom element(s).

                为你自定义的元素编写一个xml  schema文档

    <!-- myns.xsd (inside package org/springframework/samples/xml) --> <?xml version="1.0" encoding="UTF-8"?> <xsd:schemaxmlnsxsd:schemaxmlns="http://www.mycompany.com/schema/myns" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.mycompany.com/schema/myns" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:importnamespacexsd:importnamespace="http://www.springframework.org/schema/beans"/> <xsd:element name="dateformat"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="lenient" type="xsd:boolean"/> <xsd:attribute name="pattern" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema> 

    照这种形式使用

    <myns:dateformatidmyns:dateformatid="dateFormat" pattern="yyyy-MM-dd HH:mm" lenient="true"/> 

    得到的与下述代码一样

    <bean id="dateFormat" class="java.text.SimpleDateFormat"> <constructor-argvalueconstructor-argvalue="yyyy-HH-dd HH:mm"/> <property name="lenient" value="true"/> </bean> 

    备注:我schema编写能力不行,得学习

    第二步:Coding aNamespaceHandler(实现一个NamespaceHandler)

    NamespaceHandler这个接口是很简单的,只有三个方法

     init()- allows for initialization of the NamespaceHandlerand will be called by Spring before the handler is used  • BeanDefinition parse(Element, ParserContext)-  called when Spring encounters a top-level element (not nested inside a bean definition or a different namespace). This method can register bean definitions itself and/or return a bean definition.  • BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)  called when Spring encounters an attribute or nested element of a different namespace. 

    但是spring给我们提供了一个实现了大量公共的逻辑抽象类,我们只需要继承它就行了,不需要重复写很多繁琐的代码,这个类就是NamespaceHandlerSupport

    package org.springframework.samples.xml; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class MyNamespaceHandler extends NamespaceHandlerSupport {  public void init() {  registerBeanDefinitionParser("dateformat"new SimpleDateFormatBeanDefinitionParser()); 

    这个类中,你可以注册许多BeanDefinitionParsers,每一个BeanDefinitionParsers用于解析一个自定义element。

    第三步:Coding a  BeanDefinitionParser(编写一个  BeanDefinitionParser类)

    package org.springframework.samples.xml; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.util.StringUtils; import org.w3c.dom.Element; import java.text.SimpleDateFormat; public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {    protected Class getBeanClass(Element element) {  return SimpleDateFormat.class; #  }  protected void doParse(Element element, BeanDefinitionBuilder bean) {  // this will never be null since the schema explicitly requires that a value be supplied  String pattern = element.getAttribute("pattern");  bean.addConstructorArg(pattern);  // this however is an optional property  String lenient = element.getAttribute("lenient");  if (StringUtils.hasText(lenient)) {  bean.addPropertyValue("lenient", Boolean.valueOf(lenient)); 

    同样的,我们也可以继承  AbstractSingleBeanDefinitionParser 这个类   个人觉得,当你只需要注册一个BeanDefinitionParser的时候,你可以继承  AbstractSingleBeanDefinitionParser 这个抽象类,但是如果你的 NamespaceHandler需要多个 BeanDefinitionParser。你就不应该继承这个类。应该继承另外一个抽象类(已验证)

    第四步:Registering the handler and the schema(把咱们写的hanlder和schema让spring知道)

    编码已经完成了,接下来,我们需要分开将我们自定义的namespaceHandler和schema注册到spring.handlers.properties和spring.schemas.properties文件中,然后将文件放到自己的项目的META-INF文件夹中,注意,名字一定不能改。

     

    spring.handlers.properties中配置格式

    (注意,properties文件中分号是特殊字符,所以需要转义)

    http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler

     

    spring.schemas.properties中的配置格式

    (此处分号也是需要转义的)

    http\://www.mycompany.com/schema/myns/myns.xsd=org/springframework/samples/xml/myns.xsd

    第五步:现在你就可以使用了

    <?xml version="1.0" encoding="UTF-8"?> <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:myns="http://www.mycompany.com/schema/myns" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.mycompany.com/schema/myns http://www.mycompany.com/schema/myns/myns.xsd"> <!-- as a top-level bean --> <myns:dateformat id="defaultDateFormat" pattern="yyyy-MM-dd HH:mm" lenient="true"/>  <bean id="jobDetailTemplate" abstract="true">  <property name="dateFormat">  <!-- as an inner bean -->  <myns:dateformat pattern="HH:mm MM-dd-yyyy"/>  </property> </bean> </beans> 

    比较简单,算是一个介绍把。感谢

    本文出自 “菜鸟” 博客,请务必保留此出处http://1491607.blog.51cto.com/1481607/1060136

    转载请注明原文地址: https://ju.6miu.com/read-19156.html

    最新回复(0)