本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7593758
建立时间:2006年5月29日




[Spring]关于spring 2.0自定义xml 标记 (二 如何实现)
软件技术

lhwork 发表于 2006/12/30 10:13:32

看了spring test 用例,其实实现这一功能还算比较简单,主要分以下的步骤,具体的实例可以去参考spring 自带的testcase 首先定义相关xsd文件,用于验证相应的行为:  主要增加了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:     主要注册相应的解析类和装饰类     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,用于验证相应的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;        }     } 关键的一步,如何生效:                   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>   相关的测试方法:  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());     }


阅读全文(3090) | 回复(1) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.445 second(s), page refreshed 144765402 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号