空間站

          北極心空

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks
          關(guān)于spring 2.0自定義xml 標(biāo)記 (一 主要的相關(guān)類)

          在spring 2.0 中,增加了自定義xml標(biāo)記這一重大的功能。下面主要看一下spring 2.0實現(xiàn)這一功能的主要相關(guān)類:

          NamespaceHandlerResolver(接口)
          由DefaultBeanDefinitionDocumentReader使用,用于定位NamespaceHandler,指定特定的命名空間uri

          實現(xiàn)類:
          DefaultNamespaceHandlerResolver

          通過map 保存所有的對應(yīng)關(guān)系
          默認(rèn)使用spring.handlers文件來保存所有的handlers
          可以定義其他的location 如:

          String location = "org/springframework/beans/factory/xml/support/customNamespace.properties";
          NamespaceHandlerResolver resolver = new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), location);

          NamespaceHandler(接口)

          基礎(chǔ)接口,用于DefaultBeanDefinitionDocumentReader處理自定義命名空間。
          方法:
          void init();
          由DefaultBeanDefinitionDocumentReader調(diào)用在構(gòu)造完后但在解析自定義元素前。

          BeanDefinition parse(Element element, ParserContext parserContext);
          解析指定的元素。

          BeanDefinitionHolder decorate(Node element,
          BeanDefinitionHolder definition,
          ParserContext parserContext);
          執(zhí)行相應(yīng)的修飾。

          實現(xiàn)類:

          NamespaceHandlerSupport(抽象類)

          主要的三個方法:
          protected final void registerBeanDefinitionDecorator(
          String elementName,
          BeanDefinitionDecorator decorator)
          注冊decorator,通過element

          protected final void registerBeanDefinitionDecoratorForAttribute(
          String attributeName,
          BeanDefinitionDecorator decorator)
          注冊decorator,通過attr

          protected final void registerBeanDefinitionParser(
          String elementName,
          BeanDefinitionParser parser)
          注冊BeanDefinitionParser,通過element

          實際的操作由具體的BeanDefinitionDecorator 或者BeanDefinitionParser 執(zhí)行

          BeanDefinitionDecorator(接口)

          裝飾相關(guān)的自定義屬性。

          AbstractInterceptorDrivenBeanDefinitionDecorator
          用于注冊相應(yīng)的Interceptor bean 定義,使用aop代理

          其他類:

          PluggableSchemaResolver,用于自定義相關(guān)的schema,默認(rèn)的schema 保存于spring.schemas文件中

          可以通過覆蓋resolveEntity方法來裝載相應(yīng)的自定義xsd文件

          主要的執(zhí)行類:

          XmlBeanDefinitionReader

          用于處理相應(yīng)的讀取工作,其實主要的工作委派給BeanDefinitionDocumentReader

          實際的類,就介紹到這,下一節(jié)通過實例來說明如何定義自定義xml 元素


          關(guān)于spring 2.0自定義xml 標(biāo)記 (二 如何實現(xiàn))

          看了spring test 用例,其實實現(xiàn)這一功能還算比較簡單,主要分以下的步驟,具體的實例可以去參考spring 自帶的testcase

          首先定義相關(guān)xsd文件,用于驗證相應(yīng)的行為:

          主要增加了4個自定義元素和1個屬性:

          <?xml version="1.0" encoding="UTF-8" standalone="no"?>

          <xsd:schema xmlns="http://www.springframework.org/schema/beans/test"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          targetNamespace="http://www.springframework.org/schema/beans/test"
          elementFormDefault="qualified">

          <xsd:element name="testBean">
          <xsd:complexType>
          <xsd:attribute name="id" type="xsd:string" use="required" form="unqualified"/>
          <xsd:attribute name="name" type="xsd:string" use="required" form="unqualified"/>
          <xsd:attribute name="age" type="xsd:integer" use="required" form="unqualified"/>
          </xsd:complexType>
          </xsd:element>

          <xsd:element name="set">
          <xsd:complexType>
          <xsd:attribute name="name" type="xsd:string" use="required" form="unqualified"/>
          <xsd:attribute name="age" type="xsd:integer" use="required" form="unqualified"/>
          </xsd:complexType>
          </xsd:element>

          <xsd:element name="debug"/>
          <xsd:element name="nop"/>

          <xsd:attribute name="object-name" type="xsd:string"/>

          </xsd:schema>

          接著定義handler映射文件:customNamespace.properties

          http\://www.springframework.org/schema/beans/test=org.springframework.beans.factory.xml.support.TestNamespaceHandler

          定義Handler:

          主要注冊相應(yīng)的解析類和裝飾類

           

          publicclass TestNamespaceHandler extends NamespaceHandlerSupport {

          publicvoid init() {

          //相對于每個xsd中定義的元素

          registerBeanDefinitionParser("testBean", new TestBeanDefinitionParser());

          registerBeanDefinitionDecorator("set", new PropertyModifyingBeanDefinitionDecorator());

          registerBeanDefinitionDecorator("debug", new DebugBeanDefinitionDecorator());

          registerBeanDefinitionDecorator("nop", new NopInterceptorBeanDefinitionDecorator());

          registerBeanDefinitionDecoratorForAttribute("object-name", new ObjectNameBeanDefinitionDecorator());

          }

          }

           

          定義各個解析類:

          privatestaticclass TestBeanDefinitionParser implements BeanDefinitionParser {

          public BeanDefinition parse(Element element, ParserContext parserContext) {

          RootBeanDefinition definition = new RootBeanDefinition();

          definition.setBeanClass(TestBean.class);

           

          MutablePropertyValues mpvs = new MutablePropertyValues();

          mpvs.addPropertyValue("name", element.getAttribute("name"));

          mpvs.addPropertyValue("age", element.getAttribute("age"));

          definition.setPropertyValues(mpvs);

           

          parserContext.getRegistry().registerBeanDefinition(element.getAttribute("id"), definition);

           

          returnnull;

          }

          }

          privatestaticclassPropertyModifyingBeanDefinitionDecorator implements BeanDefinitionDecorator {

          public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition,

          ParserContext parserContext) {

          Element element = (Element)node;

          BeanDefinition def = definition.getBeanDefinition();

           

          MutablePropertyValues mpvs = (def.getPropertyValues() == null) ?

          new MutablePropertyValues() : def.getPropertyValues();

          mpvs.addPropertyValue("name", element.getAttribute("name"));

          mpvs.addPropertyValue("age", element.getAttribute("age"));

           

          ((AbstractBeanDefinition) def).setPropertyValues(mpvs);

          return definition;

          }

          }

          privatestaticclassDebugBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {

           

          protected BeanDefinition createInterceptorDefinition(Node node) {

          returnnew RootBeanDefinition(DebugInterceptor.class);

          }

          }

          privatestaticclassNopInterceptorBeanDefinitionDecorator extends

          AbstractInterceptorDrivenBeanDefinitionDecorator {

           

          protected BeanDefinition createInterceptorDefinition(Node node) {

          returnnew RootBeanDefinition(NopInterceptor.class);

          }

          }

          privatestaticclassObjectNameBeanDefinitionDecorator implements BeanDefinitionDecorator {

          public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition,

          ParserContext parserContext) {

          Attr objectNameAttribute = (Attr)node;

          definition.getBeanDefinition().setAttribute("objectName", objectNameAttribute.getValue());

          return definition;

          }

          }

           

          可以定義EntityResolver,用于驗證相應(yīng)的xsd

          privateclass DummySchemaResolver extends PluggableSchemaResolver {

           

          public DummySchemaResolver() {

          super(CustomNamespaceHandlerTests.this.getClass().getClassLoader());

          }

           

          public InputSource resolveEntity(String publicId, String systemId) throws IOException {

          InputSource source = super.resolveEntity(publicId, systemId);

          if (source == null) {

          Resource resource =
          new ClassPathResource("org/springframework/beans/factory/xml/support/spring-test.xsd");

          source = new InputSource(resource.getInputStream());

          source.setPublicId(publicId);

          source.setSystemId(systemId);

          }

          return source;

          }

          }

          關(guān)鍵的一步,如何生效:

          String location = "org/springframework/beans/factory/xml/support/customNamespace.properties";

          NamespaceHandlerResolver resolver = new DefaultNamespaceHandlerResolver(
          getClass().getClassLoader(), location);

          DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

          XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);

          reader.setNamespaceHandlerResolver(resolver);

          reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);

          reader.setEntityResolver(new DummySchemaResolver());

          reader.loadBeanDefinitions(getResource());

          寫一個測試xml文件:

          <?xmlversion="1.0"encoding="UTF-8"?>

          <beansxmlns="http://www.springframework.org/schema/beans"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xmlns:test="http://www.springframework.org/schema/beans/test"

          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

          http://www.springframework.org/schema/beans/testhttp://www.springframework.org/schema/beans/factory/xml/support/spring-test.xsd">

          <test:testBeanid="testBean"name="Rob Harrop"age="23"/>

          <beanid="customisedTestBean"class="org.springframework.beans.TestBean">

          <test:setname="Rob Harrop"age="23"/>

          </bean>

          <beanid="debuggingTestBean"class="org.springframework.beans.TestBean">

          <test:debug/>

          <propertyname="name"value="Rob Harrop"/>

          <propertyname="age"value="23"/>

          </bean>

          <beanid="chainedTestBean"class="org.springframework.beans.TestBean">

          <test:debug/>

          <test:nop/>

          <propertyname="name"value="Rob Harrop"/>

          <propertyname="age"value="23"/>

          </bean>

          <beanid="decorateWithAttribute"class="org.springframework.beans.TestBean"test:object-name="foo"/>

          </beans>

          相關(guān)的測試方法:

          publicvoid testSimpleParser() throws Exception {

          TestBean bean = (TestBean) this.beanFactory.getBean("testBean");

          assetTestBean(bean);

          }

          publicvoid testSimpleDecorator() throws Exception {

          TestBean bean = (TestBean) this.beanFactory.getBean("customisedTestBean");

          assetTestBean(bean);

          }

          publicvoid testProxyingDecorator() throws Exception {

          ITestBean bean = (ITestBean) this.beanFactory.getBean("debuggingTestBean");

          assetTestBean(bean);

          assertTrue(AopUtils.isAopProxy(bean));

          Advisor[] advisors = ((Advised) bean).getAdvisors();

          assertEquals("Incorrect number of advisors", 1, advisors.length);

          assertEquals("Incorrect advice class.", DebugInterceptor.class, advisors[0].getAdvice().getClass());

          }

          publicvoid testChainedDecorators() throws Exception {

          ITestBean bean = (ITestBean) this.beanFactory.getBean("chainedTestBean");

          assetTestBean(bean);

          assertTrue(AopUtils.isAopProxy(bean));

          Advisor[] advisors = ((Advised) bean).getAdvisors();

          assertEquals("Incorrect number of advisors", 2, advisors.length);

          assertEquals("Incorrect advice class.", DebugInterceptor.class, advisors[0].getAdvice().getClass());

          assertEquals("Incorrect advice class.", NopInterceptor.class, advisors[1].getAdvice().getClass());

          }

          publicvoid testDecorationViaAttribute() throws Exception {

          RootBeanDefinition beanDefinition
          = (RootBeanDefinition)this.beanFactory.getBeanDefinition("decorateWithAttribute");

          assertEquals("foo", beanDefinition.getAttribute("objectName"));

          }

          privatevoid assetTestBean(ITestBean bean) {

          assertEquals("Invalid name", "Rob Harrop", bean.getName());

          assertEquals("Invalid age", 23, bean.getAge());

          }


          posted on 2007-11-02 12:56 蘆葦 閱讀(1452) 評論(0)  編輯  收藏 所屬分類: Spring
          主站蜘蛛池模板: 景洪市| 梁山县| 牡丹江市| 库尔勒市| 堆龙德庆县| 西畴县| 门头沟区| 海城市| 即墨市| 平度市| 广饶县| 怀集县| 黄冈市| 涪陵区| 江西省| 蕲春县| 林西县| 左权县| 元朗区| 孝昌县| 望都县| 桃源县| 同江市| 萨迦县| 北安市| 天峨县| 兴海县| 嘉祥县| 广水市| 喜德县| 中西区| 额尔古纳市| 岳普湖县| 丰城市| 莱西市| 云霄县| 汪清县| 游戏| 错那县| 石柱| 巴中市|