关于spring 2.0自定义xml 标记 (一 主要的相关类)
来源:互联网 发布:销售奖励政策 知乎 编辑:程序博客网 时间:2024/06/05 22:43
转载至:北极星空(空间站)
百度下吧,文章写的不错
---------------------------------------------------------------------------------------------------------------------------------
在spring 2.0 中,增加了自定义xml标记这一重大的功能。下面主要看一下spring 2.0实现这一功能的主要相关类:
NamespaceHandlerResolver(接口)
由DefaultBeanDefinitionDocumentReader使用,用于定位NamespaceHandler,指定特定的命名空间uri
实现类:
DefaultNamespaceHandlerResolver
通过map 保存所有的对应关系
默认使用spring.handlers文件来保存所有的handlers
可以定义其他的location 如:
String location = "org/springframework/beans/factory/xml/support/customNamespace.properties";
NamespaceHandlerResolver resolver = new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), location);
NamespaceHandler(接口)
基础接口,用于DefaultBeanDefinitionDocumentReader处理自定义命名空间。
方法:
void init();
由DefaultBeanDefinitionDocumentReader调用在构造完后但在解析自定义元素前。
BeanDefinition parse(Element element, ParserContext parserContext);
解析指定的元素。
BeanDefinitionHolder decorate(Node element,
BeanDefinitionHolder definition,
ParserContext parserContext);
执行相应的修饰。
实现类:
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 执行
BeanDefinitionDecorator(接口)
装饰相关的自定义属性。
AbstractInterceptorDrivenBeanDefinitionDecorator
用于注册相应的Interceptor bean 定义,使用aop代理
其他类:
PluggableSchemaResolver,用于自定义相关的schema,默认的schema 保存于spring.schemas文件中
可以通过覆盖resolveEntity方法来装载相应的自定义xsd文件
主要的执行类:
XmlBeanDefinitionReader
用于处理相应的读取工作,其实主要的工作委派给BeanDefinitionDocumentReader
实际的类,就介绍到这,下一节通过实例来说明如何定义自定义xml 元素
关于spring 2.0自定义xml 标记 (二 如何实现)
看了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());
}
- 关于spring 2.0自定义xml 标记 (一 主要的相关类)
- 关于spring 2.0自定义xml 标记 (一 主要的相关类)
- 关于spring 2.0自定义xml 标记 (一 主要的相关类)
- 关于spring 2.0自定义xml 标记 (一 主要的相关类)
- 关于spring 2.0自定义xml 标记
- 关于spring 2.0自定义xml 标记 (二 如何实现)
- 关于spring 2.0自定义xml 标记 (二 如何实现)
- 关于spring 2.0自定义xml 标记 (二 如何实现)
- XML的主要相关技术
- spring中几个主要的类(一)InitializingBean接口
- 关于struts+spring+hibernate的相关总结(一)
- JSP中自定义标记库的使用(一)
- 关于唯一设备标记的相关链接
- Spring(一、Spring的相关概念)
- 套接字(一):套接字相关的概念和两个主要的套接字类
- 关于JQuery的相关知识(一)
- 在Spring的xml文件中配置数据源主要代码
- YAML 类XML的标记语言
- Codeforces Round #259 (Div. 2) A. Little Pony and Crystal Mine
- 【字符串匹配】KMP(implement strStr()), 正则匹配(Wildcard Matching),2-dim 动规(regular expression)
- Codeforces Round #259 (Div. 2) (最差的一次比赛。说多了都是泪)
- [算法浅析] 如何在O(1)的时间里删除单链表的结点
- LeetCode刷题笔录Combination Sum
- 关于spring 2.0自定义xml 标记 (一 主要的相关类)
- LeetCode刷题笔录Partition List
- android database 相关
- 东大OJ-Prim算法
- 8月1日 Git Branch Revert 简历应用
- 算法一(复杂度)
- Matlab微分进化算法及优化函数测试
- developer.biao.daily.20140801
- Matlab遗传算法性能测试