在 Spring 中使用 Elastic-Job 的示例以下:java
<!--配置做业注册中心 --> <reg:zookeeper id="regCenter" server-lists="${gis.dubbo.registry.address}" namespace="example-job" base-sleep-time-milliseconds="${elasticJob.zkBaseSleepTimeMilliseconds}" max-sleep-time-milliseconds="${elasticJob.zkMaxSleepTimeMilliseconds}" max-retries="${elasticJob.zkMaxRetries}" />
本文重点剖析如何在 Spring 中自定义命名空间 < reg:zookeeper/>。web
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.dangdang.com/schema/ddframe/reg" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.dangdang.com/schema/ddframe/reg" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <xsd:element name="zookeeper"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="server-lists" type="xsd:string" use="required" /> <xsd:attribute name="namespace" type="xsd:string" use="required" /> <xsd:attribute name="base-sleep-time-milliseconds" type="xsd:string" /> <xsd:attribute name="max-sleep-time-milliseconds" type="xsd:string" /> <xsd:attribute name="max-retries" type="xsd:string" /> <xsd:attribute name="session-timeout-milliseconds" type="xsd:string" /> <xsd:attribute name="connection-timeout-milliseconds" type="xsd:string" /> <xsd:attribute name="digest" type="xsd:string" /> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
xsd:schema元素详解spring
<reg:zookeeper id="regCenter" reg:server-lists="" .../>。
xsd:import
导入其余命名空间,< xsd:import namespace=“http://www.springframework.org/schema/beans”/>
表示导入spirng beans命名空间。若是目标命名空间定义文件没有指定targetNamespace,则须要使用include导入其余命令空间,例如:微信
<import namespace="tnsB" schemaLocation="B.xsd">
xsd:zookeeper> 定义zookeeper元素,xml文件中可使用reg:zookeeper/>。session
xsd:complexType,zookeeper元素的类型为复杂类型。ide
xsd:extension base=“beans:identifiedType”>继承beans命名空间identifiedType的属性。(id 定义)。svg
继承NamespaceHandlerSupport,重写init方法。源码分析
public final class RegNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("zookeeper", new ZookeeperBeanDefinitionParser()); } }
注册BeanDefinitionParser解析< reg:zookeeper/>标签,并初始化实例。ui
ZookeeperBeanDefinitionParser源码:url
public final class ZookeeperBeanDefinitionParser extends AbstractBeanDefinitionParser { @Override protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext parserContext) { BeanDefinitionBuilder result = BeanDefinitionBuilder.rootBeanDefinition(ZookeeperRegistryCenter.class);// @1 result.addConstructorArgValue(buildZookeeperConfigurationBeanDefinition(element)); // @2 result.setInitMethodName("init"); // @3 return result.getBeanDefinition(); // @4 } // ....省略部分代码 }
代码@1:构建器模式,代表< reg:zookeeper/>标签对应的实体Bean对象为 ZookeeperRegistryCenter,zk注册中心实现类。
代码@2:最终建立 ZookeeperRegistryCenter,其属性经过构造方法注入。
代码@3:设置 initMethod,至关于配置文件的 init-method 属性,代表在建立实例时将调用该方法进行初始化。
代码@4:返回 AbstractBeanDefinition 对象,方便 Spring 针对该配置建立实例。
ZookeeperBeanDefinitionParser#buildZookeeperConfigurationBeanDefinition
private AbstractBeanDefinition buildZookeeperConfigurationBeanDefinition(final Element element) { BeanDefinitionBuilder configuration = BeanDefinitionBuilder.rootBeanDefinition(ZookeeperConfiguration.class); configuration.addConstructorArgValue(element.getAttribute("server-lists")); configuration.addConstructorArgValue(element.getAttribute("namespace")); addPropertyValueIfNotEmpty("base-sleep-time-milliseconds", "baseSleepTimeMilliseconds", element, configuration); addPropertyValueIfNotEmpty("max-sleep-time-milliseconds", "maxSleepTimeMilliseconds", element, configuration); addPropertyValueIfNotEmpty("max-retries", "maxRetries", element, configuration); addPropertyValueIfNotEmpty("session-timeout-milliseconds", "sessionTimeoutMilliseconds", element, configuration); addPropertyValueIfNotEmpty("connection-timeout-milliseconds", "connectionTimeoutMilliseconds", element, configuration); addPropertyValueIfNotEmpty("digest", "digest", element, configuration); return configuration.getBeanDefinition(); }
根据< reg:zookeeper/>元素,获取 element 的server-lists、namespace 属性,使用ZookeeperConfiguration 构造方式初始化 ZookeeperConfiguration属性,而后解析其余非空属性并使用set 方法注入到 ZookeeperConfiguration 实例。
在 META-INF 目录下建立 spring.handlers、spring.schemas 文件,其内容分别是:
spring.handlers:http\://www.dangdang.com/schema/ddframe/reg=io.elasticjob.lite.spring.reg.handler.RegNamespaceHandler
格式以下:xsd文件中定义的targetNamespace=自定义namespace实现类。
spring.schemas:http\://www.dangdang.com/schema/ddframe/reg/reg.xsd=META-INF/namespace/reg.xsd
格式以下:xsd文件uri = xsd文件目录。
xsi:schemaLocation="http\://www.dangdang.com/schema/ddframe/reg/reg.xsd=META-INF/namespace/reg.xsd"
取的就是该文件的内容。而后元素解析后,而后实例化Bean并调用ZookeeperRegistryCenter的init方法,开始注册中心的启动流程。
下一篇将详细介绍elastic-job注册中心的启动流程。
欢迎加笔者微信号(dingwpmz),加群探讨,笔者优质专栏目录:
一、源码分析RocketMQ专栏(40篇+)
二、源码分析Sentinel专栏(12篇+)
三、源码分析Dubbo专栏(28篇+)
四、源码分析Mybatis专栏
五、源码分析Netty专栏(18篇+)
六、源码分析JUC专栏
七、源码分析Elasticjob专栏
八、Elasticsearch专栏(20篇+)
九、源码分析MyCat专栏