Preface
Although Dubbo has been used for a long time, in fact, its understanding is still a drop in the bucket. Last month, I read through the Netty Actual Warfare (rough understanding), and suddenly I have the desire to interpret the Dubbo source code. If it doesn't wait for me, let's get started.
Friends familiar with Dubbo may know that it uses full Spring configuration, transparent access to applications, no API intrusion to applications, just use Spring to load Dubbo configuration, Dubbo Spring based Schema extension to load.
Of course, Dubbo is also supported if you don't want to use Spring configuration and want to invoke it through API, but the official recommendation is not (guess the reason).
Today, let's talk about how Dubbo is implemented based on Schema.
Get ready
Specific implementation requires the use of the following configurations or classes:
spring.handlers: Resolve the classes used
spring.schemas: Paths for custom tags
Dubbo Namespace Handler. java: Processor
DubboBean Definition Parser. java: Parser
xxxxConfig.java: JavaBean Modeling
Realization
Here's a case study of dubbo:application
Entity class ApplicationConfig.java
Located under the com.alibaba.dubbo.config package, intercept part of the code:
public class ApplicationConfig extends AbstractConfig { private static final long serialVersionUID = 5508512956753757169L; private String name; private String version; private String owner; private String organization; private String architecture; private String environment; private String compiler; private String logger; private List<RegistryConfig> registries; private MonitorConfig monitor; private Boolean isDefault; public ApplicationConfig() { } public ApplicationConfig(String name) { setName(name); }
Write dubbo.xsd file
Under META-INF, intercept part of the code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns="http://code.alibabatech.com/schema/dubbo" 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://code.alibabatech.com/schema/dubbo"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <xsd:import namespace="http://www.springframework.org/schema/tool"/> <xsd:annotation> <xsd:documentation><![CDATA[ Namespace support for the dubbo services provided by dubbo framework. ]]></xsd:documentation> </xsd:annotation> <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:attribute name="owner" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The application owner name (email prefix). ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="organization" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The organization name. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="architecture" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The architecture. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="environment" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The application environment, eg: dev/test/run ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="compiler" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The java code compiler. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="logger" type="xsd:string"> <xsd:annotation> <xsd:documentation><![CDATA[ The application logger. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="registry" type="xsd:string" use="optional"> <xsd:annotation> <xsd:documentation><![CDATA[ The application registry. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="monitor" type="xsd:string" use="optional"> <xsd:annotation> <xsd:documentation><![CDATA[ The application monitor. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="default" type="xsd:string" use="optional"> <xsd:annotation> <xsd:documentation><![CDATA[ Is default. ]]></xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:element name="annotation" type="annotationType"> <xsd:annotation> <xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation> </xsd:annotation> </xsd:element> </xsd:schema>
As for the specific meaning of the attributes of xsd:schema, you can see
http://www.w3school.com.cn/schema/schema_elements_ref.asp
Implementation parsing of DubboBean Definition Parser and Dubbo Namespace Handler
Dubbo Namespace Handler finds a DubboBean Definition Parser based on the schema and node name, and then completes the specific parsing by DubboBean Definition Parser. So you need to inherit NamespaceHandlerSupport and implement the BeanDefinitionParser class, respectively.
Both classes are located under the com.alibaba.dubbo.config.spring.schema package. The following is part of the DubboNamespace Handler code:
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)); } }
Because DubboBean Definition Parser is too long, you can check the source code by yourselves.
Customize spring.handlers and spring.schemas
After coding, there is still some configuration work to be done. We have to tell Spring that we are going to use custom tag elements and how Spring parses elements, otherwise Spring is not that smart. Here you need two configuration files, spring.handlers and spring. schemas (under META-INF), to tell Spring the document structure of the custom tag and to parse its classes. The contents of the two documents are as follows:
spring.handlers:
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
spring.schemas:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
Attention \ is an escape, must add, or will be prompted to report errors.
spring-context-dubbo.xml
Okay, that's what we're going to end up with:
<?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: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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- Provider application information for computing dependency part of the code--> <dubbo:application name="itstyle" /> </beans>
Small railway station: https://blog.52itstyle.com