Spring源码解析自定义标签解析.docx
- 文档编号:5970997
- 上传时间:2023-01-02
- 格式:DOCX
- 页数:13
- 大小:67.06KB
Spring源码解析自定义标签解析.docx
《Spring源码解析自定义标签解析.docx》由会员分享,可在线阅读,更多相关《Spring源码解析自定义标签解析.docx(13页珍藏版)》请在冰豆网上搜索。
Spring源码解析自定义标签解析
Spring源码解析-自定义标签解析
Demo
创建接收配置的POJO
publicclassRpcServiceimplementsSerializable{
//协议名称
privateStringcontact;
//服务名称
privateStringserviceName;
//服务实现
privateStringserviceImplName;
publicRpcService(){
}
publicStringgetContact(){
returncontact;
}
publicvoidsetContact(Stringcontact){
this.contact=contact;
}
publicStringgetServiceName(){
returnserviceName;
}
publicvoidsetServiceName(StringserviceName){
this.serviceName=serviceName;
}
publicStringgetServiceImpl(){
returnserviceImplName;
}
publicvoidsetServiceImplName(StringserviceImplName){
this.serviceImplName=serviceImplName;
}
@Override
publicStringtoString(){
return"RpcService{"+
"contact='"+contact+'\''+
",serviceName='"+serviceName+'\''+
",serviceImplName='"+serviceImplName+'\''+
'}';
}
}
publicclassUserInfoService{
privateStringname="xu";
privateintage=18;
publicUserInfoService(){}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
@Override
publicStringtoString(){
return"UserInfoService{"+
"name='"+name+'\''+
",age="+age+
'}';
}
}
元素的XSD文件
xmlversion="1.0"encoding="UTF-8"?
>
//www.w3.org/2001/XMLSchema" targetNamespace=" xmlns: tns=" elementFormDefault="qualified"> Handler处理 publicclassRpcServiceNamespaceHandlerextendsNamespaceHandlerSupport{ @Override publicvoidinit(){ registerBeanDefinitionParser("service-publish",newRpcServicePublishBeanDefinitionParser()); } } BeanDefinitionParser publicclassRpcServicePublishBeanDefinitionParserextendsAbstractSingleBeanDefinitionParser{ @Override protectedvoiddoParse(Elementelement,BeanDefinitionBuilderbuilder){ Stringcontact=element.getAttribute("contact"); StringserviceName=element.getAttribute("serviceName"); StringserviceImplName=element.getAttribute("serviceImplName"); if(StringUtils.hasText(contact)){ builder.addPropertyValue("contact",contact); } if(StringUtils.hasText(serviceName)){ builder.addPropertyValue("serviceName",serviceName); } if(StringUtils.hasText(serviceImplName)){ builder.addPropertyValue("serviceImplName",serviceImplName); } } @Override protectedClass >getBeanClass(Elementelement){ returnRpcService.class; } @Override protectedStringgetBeanClassName(Elementelement){ returnRpcService.class.getSimpleName(); } } spring.handlers和spring.schemals spring.handlers spring.schemals 注意这2个文件要放在META-INF下,要不把上面这些都打jar,要不META-INF放到class目录去,否则找不到。 Test xmlversion="1.0"encoding="UTF-8"? > service-publishid="userInfoService"contact="UserInfoCenter"serviceName="UserInfoQuery" serviceImplName="qbb.rpc.UserInfoService"/> 注意添加,我的是Intellij,eclipse应该也有地方添加: Intellij: publicclassMyBeanTest{ publicstaticvoidmain(String[]args)throwsClassNotFoundException,IllegalAccessException,InstantiationException{ BeanFactoryctx=newXmlBeanFactory(newClassPathResource("spring.xml")); RpcServicerpcService=ctx.getBean("userInfoService",RpcService.class); System.out.println(rpcService); StringrpcServiceImplName=rpcService.getServiceImpl(); UserInfoServiceuserInfoService=(UserInfoService)Class.forName(rpcServiceImplName).newInstance(); System.out.println(userInfoService); } } 源码解析 之前看beanfactory的解析的时候,解析标签的时候,会区分是默认的namespaces还是自定义的: //DefaultBeanDefinitionDocumentReader protectedvoidparseBeanDefinitions(Elementroot,BeanDefinitionParserDelegatedelegate){ //默认beans标签 if(delegate.isDefaultNamespace(root)){ NodeListnl=root.getChildNodes(); for(inti=0;i Nodenode=nl.item(i); if(nodeinstanceofElement){ Elementele=(Element)node; if(delegate.isDefaultNamespace(ele)){ parseDefaultElement(ele,delegate); } else{ delegate.parseCustomElement(ele); } } } } else{ //自定义标签 delegate.parseCustomElement(root); } } 还是委托BeanDefinitionParserDelegate处理: publicBeanDefinitionparseCustomElement(Elementele){ returnparseCustomElement(ele,null); } publicBeanDefinitionparseCustomElement(Elementele,BeanDefinitioncontainingBd){ //获取uri StringnamespaceUri=getNamespaceURI(ele); //根据uri获取处理handler NamespaceHandlerhandler=this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if(ndler==null){ error("UnabletolocateSpringNamespaceHandlerforXMLschemanamespace["+namespaceUri+"]",ele); returnnull; } //解析标签,返回对应的beanDefinition returnhandler.parse(ele,newParserContext(this.readerContext,this,containingBd)); } getNamespaceHandlerResolver()-resolve //DefaultNamespaceHandlerResolver //DefaultNamespaceHandlerResolver publicNamespaceHandlerresolve(StringnamespaceUri){ //获取META-INF/spring.handlers所有配置的namespace的handler Map //获取到自定义标签解析的handler ObjecthandlerOrClassName=handlerMappings.get(namespaceUri); if(handlerOrClassName==null){ returnnull; } elseif(handlerOrClassNameinstanceofNamespaceHandler){ return(NamespaceHandler)handlerOrClassName; } else{ StringclassName=(String)handlerOrClassName; try{ Class >handlerClass=ClassUtils.forName(className,this.classLoader); //如果不是NamespaceHandle的子类的话,抛异常 if(! NamespaceHandler.class.isAssignableFrom(handlerClass)){ thrownewFatalBeanException("Class["+className+"]fornamespace["+namespaceUri+ "]doesnotimplementthe["+NamespaceHandler.class.getName()+"]interface"); } //实例化NamespaceHandler NamespaceHandlernamespaceHandler=(NamespaceHandler)BeanUtils.instantiateClass(handlerClass); //调用初始化注册beanDefinitionParser namespaceHandler.init(); handlerMappings.put(namespaceUri,namespaceHandler); returnnamespaceHandler; } catch(ClassNotFoundExceptionex){ thrownewFatalBeanException("NamespaceHandlerclass["+className+"]fornamespace["+ namespaceUri+"]notfound",ex); } catch(LinkageErrorerr){ thrownewFatalBeanException("InvalidNamespaceHandlerclass["+className+"]fornamespace["+ namespaceUri+"]: problemwithhandlerclassfileordependentclass",err); } } } //获取META-INF/spring.handlers所有配置的namespace的handler privateMap if(this.handlerMappings==null){ synchronized(this){ if(this.handlerMappings==null){ try{ //handlerMappingsLocation默认是META-INF/spring.handlers Propertiesmappings= PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation,this.classLoader); if(logger.isDebugEnabled()){ logger.debug("LoadedNamespaceHandlermappings: "+mappings); } Map CollectionUtils.mergePropertiesIntoMap(mappings,handlerMappings); this.handlerMappings=handlerMappings; } catch(IOExceptionex){ thrownewIllegalStateException( "UnabletoloadNamespaceHandlermappingsfromlocation["+this.handlerMappingsLocation+"]",ex); } } } } returnthis.handlerMappings; } 到这里获取到处理自定义标签的NamespaceHandler。 NamespaceHandler-parse //NamespaceHandlerSupport publicBeanDefinitionparse(Elementelement,ParserContextparserContext){ returnfindParserForElement(element,parserContext).parse(element,parserContext); } //获取对应的beanDefinitionParse来解析对应的标签 privateBeanDefinitionParserfindParserForElement(Elementelement,ParserContextparserContext){ StringlocalName=parserContext.getDelegate().getLocalName(element); //this.parsers需要我们在NamespaceHandler的init注册进来 BeanDefinitionParserparser=this.parsers.get(localName); if(parser==null){ parserContext.getReaderContext().fatal( "CannotlocateBeanDefinitionParserforelement["+localName+"]",element); } returnparser; } //NamespaceHandler的init注册自定义标签的beanDefinitionParse protectedfinalvoidregisterBeanDefinitionParser(StringelementName,BeanDefinitionParserparser){ this.parsers.put(elementName,parser); } 看下BeanDefinition的parser方法: //AbstractBeanDefinitionParser publicfinalBeanDefinitionparse(Elementelement,ParserContextparserContext){ //子类继承覆盖parseInternal完成解析BeanDefinition AbstractBeanDefinitiondefinition=parseInternal(element,parserContext); if(definition! =null&&! parserContext.isNested()){ try{ //bean的id,可以通过覆盖shouldGenerateId返回true,选择spring自己生成,要不然就自定义标签里面自己提供一个id Stringid=resolveId(element,definition,parserContext); if(! StringUtils.hasText(id)){ parserContext.getReaderContext().error( "Idisrequiredforelement'"+parserContext.getDelegate().getLocalName(element) +"'whenusedasatop-leveltag",element); } String[]aliases=newString[0]; Stringname=element.getAttribute(NAME_ATTRIBUTE); if(StringUtils.hasLength(name)){ aliases=StringUtils.trimArrayElements(StringUmaDelimitedListToStringArray(name)); } BeanDefinitionHolderholder=newBeanDefinitionHolder(definition,id,aliases); //注册beanDefinition到spring registerBeanDefinition(holder,parserContext.getRegistry()); if(shouldFireEvents()){ BeanComponentDefinitioncomponentDefinition=newBeanComponentDefinition(holder); postProcessComponentDefinition(componentDefinition); parserContext.registerComponent(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Spring 源码 解析 自定义 标签
![提示](https://static.bdocx.com/images/bang_tan.gif)