自定义xml标签(用netty、zk手写RPC)
从XML认识XSD
废话不多说,xsd(xml schema defition)的作用如下
Xml Schema的用途:
- 定义一个Xml文档中元素以及元素的属性
- 定义某个节点的层级关系
- 定义元素或者属性的数据类型以及默认值
直接上例子,下面这个就是一个自定义的xml标签结合了spring的标签完成的bean配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
//Spring的xsd标签的命名空间,也就是给xsd起了个别名,习惯性用http://....逼格高
xmlns="http://www.springframework.org/schema/beans"
//xsi标签定义命名,这个基本用在自定义的xsd中使用原生的标签定义
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
//自定义rpc的xsd的命名空间,就是别名啦
xmlns:rpc="http://rpc.kaer.com/schema/rpc"
//这里就是别名——实际地址的映射,可以看到也是一群装逼的http://..但是后面多了个xsd的文件名,下面告诉你怎么找
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://rpc.kaer.com/schema/rpc http://rpc.kaer.com/schema/rpc/rpc.xsd">
<!-- zk配置,保存服务信息,用的就是自定义标签了rpc:表示用的是自定义rpc的xsd里面的标签 -->
<rpc:server id="consumer_rpc" host="127.0.0.1"
port="2181" />
<!-- 服务订阅 -->
<rpc:consumer id="consumer_helloService"
api="com.kaer.rpc.demo.test.service.HelloService" alias="kaerRpc" />
<!-- 服务注册 -->
<rpc:provider id="provider_helloService"
api="com.kaer.rpc.demo.test.service.HelloService" mapper="helloService"
alias="kaerRpc" />
</beans>
首先我们要在Java工程的resources下面新建文件META-INF,在这个文件夹下面定义两个文件,分别是spring.handlers(配置了标签的解析类,就比如server这个标签应该怎么处理)和spring.schemas(别名与实际xsd文件路径的映射)
这里把rpc.xsd的定义也放在了一起,看一下两个文件的配置:
spring.handlers(其中“:”是需要转义符\的)
http://rpc.kaer.com/schema/rpc=com.kaer.rpc.demo.config.spring.MyNamespaceHandler
spring.schemas
http://rpc.kaer.com/schema/rpc/rpc.xsd=META-INF/rpc.xsd
下面一步步来,先看xsd是如何定义的
<?xml version="1.0"?>
<xsd:schema
//表示数据类型等定义来自w3
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
//表示文档中要定义的元素来自什么命名空间
targetNamespace="http://rpc.kaer.com/schema/rpc"
//表示此文档的默认命名空间是什么
xmlns="http://rpc.kaer.com/schema/rpc"
//表示要求xml文档的每一个元素都要有命名空间指定
elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- com.kaer.rpc.demo.config.ConsumerConfig -->
<xsd:element name="consumer">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="api" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[consumer]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="alias" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[consumer]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<!-- com.kaer.rpc.demo.config.ProviderConfig -->
<xsd:element name="provider">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="api" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[provider]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="mapper" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[provider]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="alias" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[provider]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<!-- com.kaer.rpc.demo.config.ServerConfig -->
<xsd:element name="server">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[server]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:integer">
<xsd:annotation>
<xsd:documentation><![CDATA[server]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
看一下MyNamespaceHandler的简单定义
public class MyNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("consumer", new MyBeanDefinitionParser(ConsumerBean.class));
registerBeanDefinitionParser("provider", new MyBeanDefinitionParser(ProviderBean.class));
registerBeanDefinitionParser("server", new MyBeanDefinitionParser(ServerBean.class));
}
}
以上就完成了从xsd到xml的定义配置。点击查看更多Xml Schema Definition
下一节将如果将服务注册到zk的节点上