Spring源码解析自定义标签解析Word文件下载.docx
《Spring源码解析自定义标签解析Word文件下载.docx》由会员分享,可在线阅读,更多相关《Spring源码解析自定义标签解析Word文件下载.docx(13页珍藏版)》请在冰豆网上搜索。
+
"
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;
UserInfoService{"
name='
+name+'
age="
+age+
元素的XSD文件
<
?
xmlversion="
1.0"
encoding="
UTF-8"
>
schemaxmlns="
http:
//www.w3.org/2001/XMLSchema"
targetNamespace="
xmlns:
tns="
elementFormDefault="
qualified"
<
elementname="
service-publish"
complexType>
attributename="
id"
type="
string"
default="
/>
contact"
serviceName"
serviceImplName"
/complexType>
/element>
/schema>
Handler处理
publicclassRpcServiceNamespaceHandlerextendsNamespaceHandlerSupport{
publicvoidinit(){
registerBeanDefinitionParser("
newRpcServicePublishBeanDefinitionParser());
BeanDefinitionParser
publicclassRpcServicePublishBeanDefinitionParserextendsAbstractSingleBeanDefinitionParser{
protectedvoiddoParse(Elementelement,BeanDefinitionBuilderbuilder){
Stringcontact=element.getAttribute("
);
StringserviceName=element.getAttribute("
StringserviceImplName=element.getAttribute("
if(StringUtils.hasText(contact)){
builder.addPropertyValue("
contact);
if(StringUtils.hasText(serviceName)){
serviceName);
if(StringUtils.hasText(serviceImplName)){
serviceImplName);
protectedClass<
getBeanClass(Elementelement){
returnRpcService.class;
protectedStringgetBeanClassName(Elementelement){
returnRpcService.class.getSimpleName();
spring.handlers和spring.schemals
spring.handlers
spring.schemals
注意这2个文件要放在META-INF下,要不把上面这些都打jar,要不META-INF放到class目录去,否则找不到。
Test
rpc:
service-publishid="
userInfoService"
contact="
UserInfoCenter"
serviceName="
UserInfoQuery"
serviceImplName="
qbb.rpc.UserInfoService"
/>
/beans>
注意添加,我的是Intellij,eclipse应该也有地方添加:
Intellij:
publicclassMyBeanTest{
publicstaticvoidmain(String[]args)throwsClassNotFoundException,IllegalAccessException,InstantiationException{
BeanFactoryctx=newXmlBeanFactory(newClassPathResource("
spring.xml"
));
RpcServicerpcService=ctx.getBean("
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<
nl.getLength();
i++){
Nodenode=nl.item(i);
if(nodeinstanceofElement){
Elementele=(Element)node;
if(delegate.isDefaultNamespace(ele)){
parseDefaultElement(ele,delegate);
else{
delegate.parseCustomElement(ele);
//自定义标签
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
publicNamespaceHandlerresolve(StringnamespaceUri){
//获取META-INF/spring.handlers所有配置的namespace的handler
Map<
String,Object>
handlerMappings=getHandlerMappings();
//获取到自定义标签解析的handler
ObjecthandlerOrClassName=handlerMappings.get(namespaceUri);
if(handlerOrClassName==null){
elseif(handlerOrClassNameinstanceofNamespaceHandler){
return(NamespaceHandler)handlerOrClassName;
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){
NamespaceHandlerclass["
namespaceUri+"
]notfound"
ex);
catch(LinkageErrorerr){
InvalidNamespaceHandlerclass["
]:
problemwithhandlerclassfileordependentclass"
err);
//获取META-INF/spring.handlers所有配置的namespace的handler
privateMap<
getHandlerMappings(){
if(this.handlerMappings==null){
synchronized(this){
//handlerMappingsLocation默认是META-INF/spring.handlers
Propertiesmappings=
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation,this.classLoader);
if(logger.isDebugEnabled()){
logger.debug("
LoadedNamespaceHandlermappings:
+mappings);
handlerMappings=newConcurrentHashMap<
();
CollectionUtils.mergePropertiesIntoMap(mappings,handlerMappings);
this.handlerMappings=handlerMappings;
catch(IOExceptionex){
thrownewIllegalStateException(
UnabletoloadNamespaceHandlermappingsfromlocation["
+this.handlerMappingsLocation+"
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()){
//bean的id,可以通过覆盖shouldGenerateId返回true,选择spring自己生成,要不然就自定义标签里面自己提供一个id
Stringid=resolveId(element,definition,parserContext);
StringUtils.hasText(id)){
parserContext.getReaderContext().error(
Idisrequiredforelement'
+parserContext.getDelegate().getLocalName(element)
+"
whenusedasatop-leveltag"
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(