看了spring test 用例,其实实现这一功能还算比较简单,主要分以下的步骤,具体的实例可以去参考spring 自带的testcase 首先定义相关xsd文件,用于验证相应的行为:
接着定义handler映射文件:customnamespace.properties 定义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 = 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( 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: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 相关的测试方法: 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 assertequals("foo", beandefinition.getattribute("objectname")); } privatevoid assettestbean(itestbean bean) { assertequals("invalid name", "rob harrop", bean.getname()); assertequals("invalid age", 23, bean.getage()); } |
闽公网安备 35060202000074号