当我们在阅读Dubbo User Guide时,在快速启动分栏中有这么一句话:
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
这里就要先说一下Spring的Schema自定义扩展的功能了,了解Spring的人都会知道,Spring配置文件中有很多标定义如:<bean/>,我们在配置bean时,按照bean语法规则配置即可,spring就能解析这个元素,原理呢这里不在详述, 本文重介绍,在Dubbo中是如何应用Spring提供了的Schema扩展机制的,spring是如何识别<dubbo:service/>,<dubbo:protocol/>,<dubbo:provider/>,<dubbo:consumer/>等用户自定义的xml标签元素的.
如果让Spring识别自动义xml标签,需要我们自己实现以下几步:
自定义 xsd Schema 文件;
编写一个我们自己的 bean;
继承NamespaceHandlerSupport 重写init()方法,这块方法作用是spring容器载入入口;
继承AbstractSingleBeanDefinitionParser类,重写getBeanClass,doParse方法, 这是解析XML元素的实现类;
新建META-INF目录,创建spring.handlers,spring.schemas两个文件,这两个文件的作用就是让spring知道,怎么解析用户自定义的元素,用什么去解析这些元素;
下面是实现的例子:
1.serviceconfig.xsd
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<xsd:schema xmlns="http://blog.csdn.net/tzqjz/schema/serviceconfig"
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://blog.csdn.net/tzqjz/schema/serviceconfig"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<xsd:import namespace="http://www.springframework.org/schema/tool" />
<xsd:element name="serviceconfig">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="ip" type="xsd:string">
<xsd:annotation>
<xsd:documentation>ip</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string">
<xsd:annotation>
<xsd:documentation>端口</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
2.ServiceConfigNamespaceHandler
public class ServiceConfigNamespaceHandler extends NamespaceHandlerSupport {public void init() {
registerBeanDefinitionParser("serviceconfig", new ServiceConfigBeanDefinitionParser());
}
}
3.ServiceConfigBeanDefinitionParser
public class ServiceConfigBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {@Override
protected Class<?> getBeanClass(Element element) {
return ServiceConfig.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder bean) {
String ip = element.getAttribute("ip");
String port = element.getAttribute("port");
bean.addPropertyValue("ip", ip);
bean.addPropertyValue("port", port);
}
}
4.ServiceConfig
public class ServiceConfig {private String ip;
private String port;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
}
5.spring.handlers
http\://blog.csdn.net/tzqjz/schema/serviceconfig=blog.csdn.net.spring.schema.ServiceConfigNamespaceHandler6.spring.schemas
http\://blog.csdn.net/tzqjz/schema/serviceconfig/serviceconfig.xsd=META-INF/serviceconfig.xsd7.applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sc="http://blog.csdn.net/tzqjz/schema/serviceconfig"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://blog.csdn.net/tzqjz/schema/serviceconfig
http://blog.csdn.net/tzqjz/schema/serviceconfig/serviceconfig.xsd">
<sc:serviceconfig id="test" ip="127.0.0.1" port="20880" />
</beans>
8.TestMain
public class TestMain {public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ServiceConfig serviceConfig = (ServiceConfig) context.getBean("test");
System.out.println(serviceConfig.getIp()+":"+serviceConfig.getPort());
}
}
输出结果:
六月 02, 2017 1:07:58 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1a86f2f1: startup date [Fri Jun 02 01:07:58 GMT+08:00 2017]; root of context hierarchy
六月 02, 2017 1:07:59 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
127.0.0.1:20880
很简单吧.