科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道spring 2.0自定义xml 标记 (二 如何实现)

spring 2.0自定义xml 标记 (二 如何实现)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

spring 2.0自定义xml 标记 (二 如何实现)

作者:baocl 来源:赛迪网技术社区 2007年11月1日

关键字: 自定义 XML spring 2.0

  • 评论
  • 分享微博
  • 分享邮件

看了spring test 用例,其实实现这一功能还算比较简单,主要分以下的步骤,具体的实例可以去参考spring 自带的testcase

首先定义相关xsd文件,用于验证相应的行为:

主要增加了4个自定义元素和1个属性:

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













接着定义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文件:

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">

相关的测试方法:

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());

}

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章