spring解析dubbo标签

8 篇文章 0 订阅

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

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

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://ttdubbo.oschina.net/schema/ttdubbo"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:tool="http://www.springframework.org/schema/tool"
	targetNamespace="http://ttdubbo.oschina.net/schema/ttdubbo">



	<xsd:complexType name="applicationType">
		<xsd:attribute name="id" type="xsd:ID">
			<xsd:annotation>
				<xsd:documentation><![CDATA[ The unique identifier for a bean. ]]></xsd:documentation>
			</xsd:annotation>
		</xsd:attribute>
		<xsd:attribute name="name" type="xsd:string" use="required">
			<xsd:annotation>
				<xsd:documentation><![CDATA[ The application name. ]]></xsd:documentation>
			</xsd:annotation>
		</xsd:attribute>
		<xsd:attribute name="version" type="xsd:string">
			<xsd:annotation>
				<xsd:documentation><![CDATA[ The application version. ]]></xsd:documentation>
			</xsd:annotation>
		</xsd:attribute>
	</xsd:complexType>




	<xsd:element name="application" type="applicationType">
		<xsd:annotation>
			<xsd:documentation><![CDATA[ The application config ]]></xsd:documentation>
		</xsd:annotation>
	</xsd:element>
</xsd:schema>
 

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文件中定义:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:ttdubbo="http://ttdubbo.oschina.net/schema/ttdubbo"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
	 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
	 http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	 	http://ttdubbo.oschina.net/schema/ttdubbo http://ttdubbo.oschina.net/schema/ttdubbo.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

	<!-- 导入properity文件-->
	<context:property-placeholder  location="classpath*:conf/*.properties"/>
	
	
	
	
	<context:component-scan base-package="cn.andy.dubbo"></context:component-scan>
	
	
	
		
	<import resource="classpath*:spring/applicationContext-dubbo.xml"/>
	
	<ttdubbo:application id="app1"  name="ttdubboTest" version="0.0.1" />
	
	<ttdubbo:registry id="reg1" address="192.168.1.101" port="80" />
	
	
	
</beans>

然后,在测试文件中

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标签

<xsd:complexType name="abstractServiceType">
		<xsd:complexContent>
			<xsd:extension base="abstractInterfaceType">
                <xsd:attribute name="register" type="xsd:string" use="optional">
                    <xsd:annotation>
                        <xsd:documentation><![CDATA[ The service can be register to registry. ]]></xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
				<xsd:attribute name="version" type="xsd:string" use="optional" default="0.0.0">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service version. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="group" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service group. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="deprecated" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ whether the service is deprecated. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="delay" type="xsd:string" use="optional" default="0">
	               	<xsd:annotation>
	               		<xsd:documentation>
	               			<![CDATA[ The service export delay millisecond. ]]>
	               		</xsd:documentation>
	               	</xsd:annotation>
	            </xsd:attribute>
	            <xsd:attribute name="export" type="xsd:string" use="optional">
	               	<xsd:annotation>
	               		<xsd:documentation>
	               			<![CDATA[ The service is export. ]]>
	               		</xsd:documentation>
	               	</xsd:annotation>
	            </xsd:attribute>
	            <xsd:attribute name="weight" type="xsd:string" use="optional">
	               	<xsd:annotation>
	               		<xsd:documentation>
	               			<![CDATA[ The service weight. ]]>
	               		</xsd:documentation>
	               	</xsd:annotation>
	            </xsd:attribute>
	            <xsd:attribute name="document" type="xsd:string" use="optional">
	               	<xsd:annotation>
	               		<xsd:documentation>
	               			<![CDATA[ The service document. ]]>
	               		</xsd:documentation>
	               	</xsd:annotation>
	            </xsd:attribute>
				<xsd:attribute name="dynamic" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ the service registered to the registry is dynamic(true) or static(false). ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="token" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service use token. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="accesslog" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service use accesslog. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="executes" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service allow execute requests. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="protocol" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service protocol. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:anyAttribute namespace="##other" processContents="lax" />
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>
	
	<xsd:complexType name="referenceType">
		<xsd:complexContent>
			<xsd:extension base="abstractReferenceType">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:element ref="method" minOccurs="0" maxOccurs="unbounded" />
					<xsd:element ref="parameter" minOccurs="0" maxOccurs="unbounded" />
				</xsd:choice>
				<xsd:attribute name="interface" type="xsd:token" use="required">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service interface class name. ]]></xsd:documentation>
						<xsd:appinfo>
							<tool:annotation>
								<tool:expected-type type="java.lang.Class"/>
							</tool:annotation>
						</xsd:appinfo>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="url" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ Provider list url. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="client" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ Protocol transport client type. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="consumer" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ Deprecated. Replace to reference-default. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:attribute name="protocol" type="xsd:string" use="optional">
					<xsd:annotation>
						<xsd:documentation><![CDATA[ The service protocol. ]]></xsd:documentation>
					</xsd:annotation>
				</xsd:attribute>
				<xsd:anyAttribute namespace="##other" processContents="lax" />
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>







<xsd:element name="service" type="serviceType">
		<xsd:annotation> 
			<xsd:documentation><![CDATA[ Export service config ]]></xsd:documentation> 
		</xsd:annotation>
	</xsd:element>
	
	<xsd:element name="reference" type="referenceType">
		<xsd:annotation> 
			<xsd:documentation><![CDATA[ Reference service config ]]></xsd:documentation> 
		</xsd:annotation>
	</xsd:element>

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值