前面四篇文章我们说明了dubbo了四个内核。这一篇我们分析dubbo是如何把dubbo的xml配置文件中的信息变成一个bean然后注册到spring容器中
在说明dubbo与spring融合之前,我们先说明如果完成spring的自定义配置一般需要以下5个步骤
1.设计配置属性和JavaBean
2.编写XSD文件,是用来校验xml规范的
3.编写NamespaceHandler和BeanDefinitionParser完成解析工作
4.填写spring.handler和spring.schemas串联所有部件
5.在Bean文件中应用
首先编写一个javaBean
public class People { private String id; private String name; private Integer age; 。。get/set方法忽略 }
然后编写
NamespaceHandler public class MyNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("people", new PeopleBeanDefinitionParser()); } }
再编写BeanDefinitionParser
public class PeopleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { protected Class getBeanClass(Element element) { return People.class; } protected void doParse(Element element, BeanDefinitionBuilder bean) { String name = element.getAttribute("name"); String age = element.getAttribute("age"); String id = element.getAttribute("id"); if (StringUtils.hasText(id)) { bean.addPropertyValue("id", id); } if (StringUtils.hasText(name)) { bean.addPropertyValue("name", name); } if (StringUtils.hasText(age)) { bean.addPropertyValue("age", Integer.valueOf(age)); } } }
再编写xsd文件
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://study.163.com/u/ykt1461577211836/schema/people" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://study.163.com/u/ykt1461577211836/schema/people" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans" /> <xsd:element name="people"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="age" type="xsd:int" /> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
在spring.handlers文件中添加NamespaceHandler的路径
http\://study.163.com/u/ykt1461577211836/schema/people=xxxxxx.MyNamespaceHandler
在spring.schemas文件中添加xsd路径
http\://study.163.com/u/ykt1461577211836/schema/people.xsd=META-INF/people.xsd
最后我们编写xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://study.163.com/u/ykt1461577211836/schema/people" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://study.163.com/u/ykt1461577211836/schema/people http://study.163.com/u/ykt1461577211836/schema/people.xsd"> <dubbo:people id="zhangqi" name="ace" age="18"/> </beans>
编写测试类 package com.soa.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.soa.other.spring.schema.People; public class TestSchema { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("/xml/application.xml"); People p = (People)ctx.getBean("dubbo"); System.out.println(p.getId()); System.out.println(p.getName()); System.out.println(p.getAge()); } } 这时候console中就会打印出zhangqi、ace、18
-------------------------------------------
接下去我们看dubbo中的这几个文件
dubbo的spring.handler中配置信息是这样的
我们找到DubboNamespaceHandlder
public class DubboNamespaceHandler extends NamespaceHandlerSupport { static { Version.checkDuplicate(DubboNamespaceHandler.class); } @Override 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("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true)); registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.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 AnnotationBeanDefinitionParser()); } }
这里就有很多非常熟悉的影子,service、provider之类的
这里的javabean就是ServiceBean、ProviderConfig等
BeanDefinitionParser就是DubboBeanDefinitionParser
可以看到xsd文件是dubbo.xsd
找到dubbo.xsd,随便看一组标签
<xsd:complexType name="serviceType"> <xsd:complexContent> <xsd:extension base="abstractServiceType"> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="method" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="beans:property" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> <xsd:attribute name="interface" type="xsd:token" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ Defines the interface to advertise for this service in the service registry. ]]></xsd:documentation> <xsd:appinfo> <tool:annotation> <tool:expected-type type="java.lang.Class"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="ref" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The service implementation instance bean id. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="class" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The service implementation class name. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="path" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The service path. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="provider" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ Deprecated. Replace to protocol. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="generic" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ Generic service. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:anyAttribute namespace="##other" processContents="lax"/> </xsd:extension> </xsd:complexContent> </xsd:complexType>
里面的一些标签是不是很熟悉?,都是<dubbo:service>中的一些标签
详细的比如DubboBeanDefinitionParser ServiceBean比较负责,我们会在后续文章中分析。。。
本节完