spring解析dubbo标签

1、spring自定义标签的步骤(参考https://my.oschina.net/lenglingx/blog/889662)

a、编写xsd文件描述自定义的元素。看下面的代码实例,这里定义了application。其中上面的代码是具体的元素定义,下面的是自定义元素名。






	
		
			
				
			
		
		
			
				
			
		
		
			
				
			
		
	




	
		
			
		
	

 

b、编写标签对应的实体类:

public class Application {
	private String id;
	private String name;
	private String version;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	@Override
	public String toString() {
		return "Application [id=" + id + ", name=" + name + ", version=" + version + "]";
	}

}

c、编写标签的解析类

/**  
 * All rights Reserved, Designed By www.tydic.com
 * @Title:  ApplicationBeanDefinitionParser.java   
 * @Package ApplicationBeanDefinitionParser   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: andyzhu    
 * @date:   2018年10月8日 上午11:14:30   
 * @version V1.0 
 * @Copyright: 2018 www.acc.com Inc. All rights reserved. 
 * 注意:禁止外泄以及用于其他的商业目
 */  
package cn.andy.testdubbo;



import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

/**
 * @author sks
 *
 */
public class ApplicationBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
	private final Class beanClass;

	private final boolean required;
	
	public ApplicationBeanDefinitionParser(Class beanClass, boolean required) {
		this.beanClass = beanClass;
		this.required = required;
	}

	protected Class getBeanClass(Element element) {
		return Application.class;
	}

	protected void doParse(Element element, BeanDefinitionBuilder bean) {
		String id = element.getAttribute("id");
		String name = element.getAttribute("name");
		String version = element.getAttribute("version");
		if (StringUtils.hasText(id)) {
			bean.addPropertyValue("id", id);
		}
		if (StringUtils.hasText(name)) {
			bean.addPropertyValue("name", name);
		}
		if (StringUtils.hasText(version)) {
			bean.addPropertyValue("version", version);
		}
	}
}

d 、编写命令空间处理类,指定自定义的标签的解析类。

/**  
 * All rights Reserved, Designed By www.tydic.com
 * @Title:  TtdubboNamespaceHandler.java   
 * @Package cn.andy.testdubbo   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: andyzhu    
 * @date:   2018年10月8日 下午1:58:31   
 * @version V1.0 
 * @Copyright: 2018 www.acc.com Inc. All rights reserved. 
 * 注意:禁止外泄以及用于其他的商业目
 */  
package cn.andy.testdubbo;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

/**
 * @author sks
 *
 */
public class TtdubboNamespaceHandler extends NamespaceHandlerSupport {

	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.xml.NamespaceHandler#init()
	 */
	@Override
	public void init() {
		// TODO Auto-generated method stub
		registerBeanDefinitionParser("application", new ApplicationBeanDefinitionParser(Application.class, true));
		
	}

}

e、编写spring.handlers和spring.schemas,这两个文件都在resources目录下的META-INF文件夹中

spring.handlers文件内容,http后面的\是转义字符,注意中间的等号

http\://ttdubbo.oschina.net/schema/ttdubbo=cn.andy.testdubbo.TtdubboNamespaceHandler

spring.schemas文件内容:

http\://ttdubbo.oschina.net/schema/ttdubbo.xsd=META-INF/ttdubbo.xsd

f、测试

在spring的xml文件中定义:




	
	
	
	
	
	
	
	
	
	
		
	
	
	
	
	
	
	
	


然后,在测试文件中

public class Test {
	
	public static void main(String[] args) {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-service.xml");
		
		Application application1 = (Application) context.getBean("app1");
		System.out.println(application1.toString());
		
		
		
		System.out.println("Hello World!");
	}

}

例子下载地址https://download.csdn.net/download/andyzhu_2005/10814375

2、 dubbo的标签解析

通过上面的流程,来看看dubbo的标签解析是否是这样子的:

a、在dubbo的源码目录下的META-INF文件夹中,找到的dubbo.xsd文件。里面有各个标签的元素定义:我们关注两个,service和reference标签


		
			
                
                    
                        
                    
                
				
					
						
					
				
				
					
						
					
				
				
					
						
					
				
				
	               	
	               		
	               			
	               		
	               	
	            
	            
	               	
	               		
	               			
	               		
	               	
	            
	            
	               	
	               		
	               			
	               		
	               	
	            
	            
	               	
	               		
	               			
	               		
	               	
	            
				
					
						
					
				
				
					
						
					
				
				
					
						
					
				
				
					
						
					
				
				
					
						
					
				
				
			
		
	
	
	
		
			
				
					
					
				
				
					
						
						
							
								
							
						
					
				
				
					
						
					
				
				
					
						
					
				
				
					
						
					
				
				
					
						
					
				
				
			
		
	








		 
			 
		
	
	
	
		 
			 
		
	

b、在spring.handlers和spring.schemas写入DubboNamespaceHandler和dubbo.xsd。

其中,DubboNamespaceHandler的内容是:

/*
* Copyright 1999-2011 Alibaba Group.
*  
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*  
*      http://www.apache.org/licenses/LICENSE-2.0
*  
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.config.spring.schema;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

import com.alibaba.dubbo.common.Version;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.ModuleConfig;
import com.alibaba.dubbo.config.MonitorConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;

/**
* DubboNamespaceHandler
* 
* @author william.liangf
* @export
*/
public class DubboNamespaceHandler extends NamespaceHandlerSupport {

   static {
   	Version.checkDuplicate(DubboNamespaceHandler.class);
   }

   public void init() {
       registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
       registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
       registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
       registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
       registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
       registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
       registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
       registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
       registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
       registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
   }

}

这里,对dubbo自定的标签分别进行了解析。其中,service标签就生成了ServiceBean类,而reference就生成了ReferenceBean类。

3、看ReferenceBean类

public class ReferenceBean extends ReferenceConfig implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean
ReferenceBean是实现了FactoryBean接口的类,我们知道,Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean,这两种Bean都被容器管理,但工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象。
所以,查看ReferenceBean的getObject()方法,

 public Object getObject() throws Exception {
        return get();
    }

    public synchronized T get() {
        if (destroyed){
            throw new IllegalStateException("Already destroyed!");
        }
    	if (ref == null) {
    		init();
    	}
    	return ref;
    }

这里的 return get();就是我们的消费端初始化的开始。

4、看ServiceBean类

public class ServiceBean extends ServiceConfig implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware{}
ServiceBean实现了ApplicationListener接口,其在初始化完成后,会回调onApplicationEvent方法:

    public void onApplicationEvent(ApplicationEvent event) {
        if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
        	if (isDelay() && ! isExported() && ! isUnexported()) {
                if (logger.isInfoEnabled()) {
                    logger.info("The service ready on spring started. service: " + getInterface());
                }
                export();
            }
        }
    }

这个方法就是服务端发布服务的开始。

5、附上eclipse不识别dubbo标签的解决办法

https://blog.csdn.net/agony_sun/article/details/76853087

你可能感兴趣的:(java,dubo)