在 Spring 中使用 Elastic-Job 的示例如下:
<!--配置作业注册中心 --><reg:zookeeper id="regCenter" server-lists="${gis.dubbo.registry.address}" namespace="example-job" -sleep-time-milliseconds="${elasticJob.zk SleepTimeMilliseconds}" max-sleep-time-milliseconds="${elasticJob.zkMaxSleepTimeMilliseconds}" max-retries="${elasticJob.zkMaxRetries}" />本文重点剖析如何在 Spring 中自定义命名空间 < reg:zookeeper/>。
1、在 -INF目录下定义xsd文件,Elastic-Job reg.xsd文件定义如下:
<? version="1.0" encoding="UTF-8"?><xsd:schema ns="http://www.dangdang.com/schema/dd /reg" ns:xsd="http://www.w3.org/2001/ Schema" ns:beans="http://www.spring work.org/schema/beans" targetNamespace="http://www.dangdang.com/schema/dd /reg" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.spring work.org/schema/beans"/> <xsd:element name="zookeeper"> <xsd:complexType> <xsd:complexContent> <xsd:extension ="beans:identifiedType"> <xsd:attribute name="server-lists" type="xsd:string" use="required" /> <xsd:attribute name="namespace" type="xsd:string" use="required" /> <xsd:attribute name=" -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元素详解
- ns="http://www.dangdang.com/schema/dd /reg":定义默认命名空间。如果元素没有前缀,默认为该命名空间下的元素。
- ns:xsd="http://www.w3.org/2001/ Schema",引入xsd命名空间,该命名空间的URL为http://www.w3.org/2001/ Schema,元素前缀为xsd。
- ns:beans="http://www.spring work.org/schema/beans",引入Spring beans命名空间. ns:xx=""表示引入已存在的命名空间。
- targetNamespace="http://www.dangdang.com/schema/dd /reg":定义该命名空间所对应的url,在 文件中如果要使用< reg:xx/>,其xsi:schemaLocation定义reg.xsd路径时必须以该值为键,例如应用程序中定义elasticjob的 文件如下:
- elementFormDefault="qualified":指定该xsd所对应的实例 文件,引用该文件中定义的元素必须被命名空间所限定。例如在reg.xsd中定义了zookeeper这个元素,那么在spring-elastic-job. ( 文档实例)中使用该元素来定义时,必须这样写: ,而不能写出。
attributeFormDefault:指定该xsd所对应的示例 文件,引用该文件中定义的元素属性是否需要被限定,unqualified表示不需要被限定。如果设置为qualified,则则为错误写法,正确写法如下:
<reg:zookeeper id="regCenter" reg:server-lists="" .../>。
- xsd:import
导入其他命名空间,< xsd:import namespace="http://www.spring work.org/schema/beans"/>
表示导入spirng beans命名空间。如果目标命名空间定义文件没有指定targetNamespace,则需要使用include导入其他命令空间,例如:
<import namespace="tnsB" schemaLocation="B.xsd"> - xsd:zookeeper> 定义zookeeper元素, 文件中可以使用reg:zookeeper/>。
- xsd:complexType,zookeeper元素的类型为复杂类型。
- xsd:extension ="beans:identifiedType">继承beans命名空间identifiedType的属性。(id 定义)。
2、定义NamespaceHandlerSupport实现类。
继承NamespaceHandlerSupport,重写init方法。
public final class RegNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("zookeeper", new ZookeeperBeanDefinitionParser()); }}注册BeanDefinitionParser解析< reg:zookeeper/>标签,并初始化实例。
ZookeeperBeanDefinitionParser源码:
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(" -sleep-time-milliseconds", " SleepTimeMilliseconds", 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 实例。
3、将自定义的 NameSpace、xsd 文件纳入 Spring 的管理范围内。
在 -INF 目录下创建 spring.handlers、spring.schemas 文件,其内容分别是:
spring.handlers:http://www.dangdang.com/schema/dd /reg=io.elasticjob.lite.spring.reg.handler.RegNamespaceHandler格式如下:xsd文件中定义的targetNamespace=自定义namespace实现类。
spring.schemas:http://www.dangdang.com/schema/dd /reg/reg.xsd= -INF/namespace/reg.xsd格式如下:xsd文件uri = xsd文件目录。
xsi:schemaLocation="http://www.dangdang.com/schema/dd /reg/reg.xsd= -INF/namespace/reg.xsd"取的就是该文件的内容。然后元素解析后,然后实例化Bean并调用ZookeeperRegistryCenter的init方法,开始注册中心的启动流程。
下一篇将详细介绍elastic-job注册中心的启动流程。
原文发布时间为:2019-11-28
本文作者:丁威,《RocketMQ技术内幕》作者。
本文来自中间件兴趣圈,了解相关信息可以关注中间件兴趣圈。
继续阅读与本文标签相同的文章
-
新规上线,为你盘点百元产品薅羊毛大法
2026-05-18栏目: 教程
-
豆瓣评分9.1,这本计算机经典名著,我读到凌晨三点
2026-05-18栏目: 教程
-
Fun 3.0 发布——资源部署、依赖下载、代码编译等功能又又又增强啦!
2026-05-18栏目: 教程
-
IoT生态精刊2019云栖特刊来了【下载】
2026-05-18栏目: 教程
-
自从来了阿里云做视频研发,我的生活发生了翻天覆地的变化
2026-05-18栏目: 教程
