看了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());
??? }
?
posted on 2006-10-27 18:18
布衣郎 閱讀(833)
評論(0) 編輯 收藏 所屬分類:
spring