微服务框架开发(二)—扩展spring schema

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

一、实体bean的定义 回顾一下我们需要定义的4个标签

  • 定义注册中心标签:
<xmen:registry name="registry" regProtocol="zookeeper" address="127.0.0.1:2181" connectTimeout="2000"/>
  • 定义服务协议标签
<xmen:protocol name="xmen" port="20000" />
  • 定义服务提供标签:
<xmen:service interface="xxx.xxx.xxx.service" class="xxx" port="8000"/>或者
<xmen:service interface="xxx.xxx.xxx.service" ref="xxx" port="8000"/>
  • 定义服务引用标签:
<xmen:referer id="xxxService" interface="xxx.xxx.xxx.service"/>

UML图设计如下

  • RegistyConfig、ServiceConfig、RefererConfig分别继承自抽象类AbstractConfig,并分别定义了三个标签的相关属性。ServiceConfigBean、RefererConfigBean用于实现spring的相关接口,达到对配置文件中bean进行处理的目的。 输入图片说明

二、定义xsd文件(xmen.xsd)

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.solid4j.com/schema/xmen" xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:tool="http://www.springframework.org/schema/tool" xmlns:beans="http://www.springframework.org/schema/beans"targetNamespace="http://www.solid4j.com/schema/xmen"><xsd:import namespace="http://www.w3.org/XML/1998/namespace" /><xsd:import namespace="http://www.springframework.org/schema/tool" /><xsd:import namespace="http://www.springframework.org/schema/beans" /><xsd:complexType name="abstractConfig"><xsd:anyAttribute /></xsd:complexType><xsd:complexType name="abstractRegistryConfig"><xsd:complexContent><xsd:extension base="abstractConfig"><xsd:attribute name="id" type="xsd:ID" /><xsd:attribute name="name" type="xsd:string" use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 注册名称. ]]></xsd:documentation></xsd:annotation></xsd:attribute><xsd:attribute name="regProtocol" type="xsd:string"use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 注册协议. ]]></xsd:documentation></xsd:annotation></xsd:attribute><xsd:attribute name="address" type="xsd:string" use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 注册中心地址. ]]></xsd:documentation></xsd:annotation></xsd:attribute><xsd:attribute name="connectTimeout" type="xsd:integer"use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 注册中心连接超时时间(毫秒). ]]></xsd:documentation></xsd:annotation></xsd:attribute></xsd:extension></xsd:complexContent></xsd:complexType><xsd:complexType name="abstractProtocolConfig"><xsd:complexContent><xsd:extension base="abstractConfig"><xsd:attribute name="id" type="xsd:ID" /><xsd:attribute name="name" type="xsd:string" use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 协议名称. ]]></xsd:documentation></xsd:annotation></xsd:attribute><xsd:attribute name="port" type="xsd:integer" use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 服务端口 ]]></xsd:documentation></xsd:annotation></xsd:attribute></xsd:extension></xsd:complexContent></xsd:complexType><xsd:complexType name="abstractServiceConfig"><xsd:complexContent><xsd:extension base="abstractConfig"><xsd:attribute name="id" type="xsd:ID" /><xsd:attribute name="interface" type="xsd:token"><xsd:annotation><xsd:documentation><![CDATA[ 定义接口,在注册中心中注册 ]]></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" use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 接口实现 ]]></xsd:documentation></xsd:annotation></xsd:attribute><xsd:attribute name="class" type="xsd:string" use="optional"><xsd:annotation><xsd:documentation><![CDATA[ 接口实现 ]]></xsd:documentation></xsd:annotation></xsd:attribute></xsd:extension></xsd:complexContent></xsd:complexType><xsd:complexType name="abstractRefererConfig"><xsd:complexContent><xsd:extension base="abstractConfig"><xsd:attribute name="id" type="xsd:ID" /><xsd:attribute name="interface" type="xsd:token" use="required"><xsd:annotation><xsd:documentation><![CDATA[ 调用的接口 ]]></xsd:documentation><xsd:appinfo><tool:annotation><tool:expected-type type="java.lang.Class" /></tool:annotation></xsd:appinfo></xsd:annotation></xsd:attribute></xsd:extension></xsd:complexContent></xsd:complexType><xsd:element name="registry" type="abstractRegistryConfig"><xsd:annotation><xsd:documentation><![CDATA[ 注册中心配置 ]]></xsd:documentation></xsd:annotation></xsd:element><xsd:element name="protocol" type="abstractProtocolConfig"><xsd:annotation><xsd:documentation><![CDATA[ 服务协议 ]]></xsd:documentation></xsd:annotation></xsd:element><xsd:element name="service" type="abstractServiceConfig"><xsd:annotation><xsd:documentation><![CDATA[ 服务配置 ]]></xsd:documentation></xsd:annotation></xsd:element><xsd:element name="referer" type="abstractRefererConfig"><xsd:annotation><xsd:documentation><![CDATA[ 引用服务配置 ]]></xsd:documentation></xsd:annotation></xsd:element>
</xsd:schema>

三、定义handler处理文件(spring.schemas和spring.handlers)

http\://www.solid4j.com/schema/xmen.xsd=META-INF/xmen.xsdhttp\://www.solid4j.com/schema/xmen=com.solid4j.xmen.config.spring.handler.XmenNamespaceHandler

四、编写具体的Handler类

public class XmenNamespaceHandler extends NamespaceHandlerSupport {@Overridepublic void init() {registerBeanDefinitionParser("registry", new XmenBeanDefinitionParser(RegistryConfig.class, true));registerBeanDefinitionParser("protocol", new XmenBeanDefinitionParser(ProtocolConfig.class, true));registerBeanDefinitionParser("service", new XmenBeanDefinitionParser(ServiceConfigBean.class, true));registerBeanDefinitionParser("referer", new XmenBeanDefinitionParser(RefererConfigBean.class, false));}
}
public class XmenBeanDefinitionParser implements BeanDefinitionParser {private static final Logger LOGGER = LoggerFactory.getLogger(BeanDefinitionParser.class);private final Class<?> beanClass;private final boolean required;public XmenBeanDefinitionParser(Class<?> beanClass, boolean required) {this.beanClass = beanClass;this.required = required;}@Overridepublic BeanDefinition parse(Element element, ParserContext parseContext) {try {return parse(element, parseContext, beanClass, required);} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}private BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) throws ClassNotFoundException {RootBeanDefinition bd = new RootBeanDefinition();bd.setBeanClass(beanClass);bd.setLazyInit(false);String id = element.getAttribute("id");if ((id == null || id.length() == 0) && required) {String generatedBeanName = element.getAttribute("name");if (generatedBeanName == null || generatedBeanName.length() == 0) {generatedBeanName = element.getAttribute("class");}if (generatedBeanName == null || generatedBeanName.length() == 0) {generatedBeanName = beanClass.getName();}id = generatedBeanName;int counter = 2;while (parserContext.getRegistry().containsBeanDefinition(id)) {id = generatedBeanName + (counter++);}}if (id != null) {if (parserContext.getRegistry().containsBeanDefinition(id)) {throw new IllegalStateException("Duplicate spring bean config, id = " + id);}parserContext.getRegistry().registerBeanDefinition(id, bd);}bd.getPropertyValues().addPropertyValue("id", id);if(ServiceConfigBean.class.equals(beanClass)) {String className = element.getAttribute("class");if(className != null && className.length() > 0) {RootBeanDefinition classDefinition = new RootBeanDefinition();classDefinition.setBeanClass(Class.forName(className, true, Thread.currentThread().getContextClassLoader()));classDefinition.setLazyInit(false);bd.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));}}for (Method setter : beanClass.getMethods()) {String name = setter.getName();if (name.length() <= 3 || !name.startsWith("set") || !Modifier.isPublic(setter.getModifiers())) {continue;}String property = name.substring(3, 4).toLowerCase() + name.substring(4);if ("id".equals(property)) {bd.getPropertyValues().addPropertyValue("id", id);continue;}String value = element.getAttribute(property);value = value.trim();if (value.length() == 0 || value == null) {continue;}Object reference;if ("ref".equals(property)) {reference = new RuntimeBeanReference(value);} else {reference = new TypedStringValue(value);}bd.getPropertyValues().addPropertyValue(property, reference);}return bd;}
}

转载于:https://my.oschina.net/solidwang/blog/800964

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何找tensorflow-gpu版本对应的cuda和cudnn

第一步 先创建一个虚拟环境&#xff08;我是在anaconda Prompt中创建&#xff09;&#xff1a;conda create -n TF1.14 python3.6 第二步 进入虚拟环境conda activate TF1.14 第三步 安装tensorflow-gpu版本 pip install tensorflow-gpu1.14.0 -i HTTPS://pypi.doubanio…

基于干净语言和好奇心的敏捷指导

\关键要点\\通过简单的问题可以挖掘出产品中包含的真正有价值的信息&#xff0c;以及我们所期望的合作方式。\\t在以“干净问题”为基础的文化中&#xff0c;没有问题会遭到嘲笑&#xff0c;而且不存在“愚蠢”的问题。\\t“尽其所能地工作”和“干净反馈”等练习可以帮助敏捷团…

origin如何绘制双y轴曲线_Origin用矩阵绘制多层曲面映射图

点击上方关注点击下方点赞【导读】怎样绘制多曲面映射图&#xff1f;1.矩阵数据的准备1.1 XYYYY型数据我们在实验中得到一张Excel表格一列X表示电场强度&#xff0c;负载量不同的多列Y又分为Pm、Pr两组。那么我们需要分别构造Pm和Pr两组XYYYY型数据表。那么全选Pr表中的XYYYY型…

北京大学Tensorflow2.0笔记

激活函数 目前很少用这个激活函数&#xff0c;因为在深度神经网络中更新参数时需要从输出层到输入层逐层进行链式求导&#xff0c;而sigmoid函数倒数值为0-0.25之间&#xff0c;链式求导需要多层导数连续相乘&#xff0c;会出现多个0-0.25之间的连续相乘&#xff0c;结果趋于零…

开源新工具 Azure Developer CLI

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;5分钟)翻译自 Savannah Ostrowski 的博客今天&#xff0c;我们很高兴地宣布 Azure Developer CLI (azd) 公共预览版——一种新的开源工具&#xff0c;可加快入门Azure 所需的时间。Azure Developer CLI 提供了对开发者…

MapReduce中的InputFormat(1)概述

1 概念InputFormat用于描述输入数据的格式&#xff0c;提供以下两个功能&#xff1a;A、数据切分&#xff1a;按照某种策略将输入的数据切分成若干split&#xff0c;以便确定Map Task个数&#xff0c;以及对应的Split。B、提供数据&#xff1a;为Mapper提供输入数据&#xff0c…

在anaconda中运行jupyter notebook,无法自动打开浏览器的解决方案,亲测100%有效

运行jupyter notebook&#xff0c;无法自动打开浏览器的解决方案 第一步 找到 Jupyter_notebook_config.py文件&#xff0c;无论你anaconda装在哪个盘&#xff0c;这个文件一般都在C盘&#xff0c;我的在C:\Users\wyf峰.jupyter 如果没有可以在anaconda prompt中输入以下语句…

本地配置_Hadoop本地模式的安装配置

Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构&#xff0c;它可以使用户在不了解分布式底层细节的情況下开发分布式程序&#xff0c;充分利用集群的威力进行高速运算和存储。从其定义就可以发现&#xff0c;它解決了两大问题&#xff1a;大数据存储、大数据分析。也…

基于 Filter 实现条件路由

基于 filter 实现条件路由Intro在我们的项目有几个测试用的接口&#xff0c;有的接口我们往往不想在生产环境上使用&#xff0c;于是会在代码里判断当前环境是不是生产环境&#xff0c;如果不是生产环境才允许执行&#xff0c;否则就返回一个错误&#xff0c;这样的接口多了之后…

ORM框架通过映射(反射)获取数据库的数据

ORM&#xff08;Object Relational Mapping&#xff09;框架采用元数据来描述对象一关系映射细节&#xff0c;元数据一般采用XML格式&#xff0c;并且存放在专门的对象一映射文件中。只要提供了持久化类与表的映射关系&#xff0c;ORM框架在运行时就能参照映射文件的信息&#…

找不到r低版本_R 语言与数据挖掘直播班开始招生,生信分析帮你发高分文章

数据单薄很难支撑文章内容&#xff1f;数据有了不知道怎么处理作出高级的图片&#xff1f;这个时候需要的是生信分析——深度的数据挖掘和分析处理&#xff0c;可以帮助临床医生通过数据处理得到自己想要的信息&#xff0c;更快速地发文章。学习哪种生信分析的工具&#xff1f;…

读两本敦煌书杂记-敦煌由盛转衰(二)

公元420-589年&#xff0c;中国分为南北两个部分&#xff08;史称魏晋南北朝&#xff0c;由西晋末年八王之乱引起&#xff0c;北方游牧少数民族趁机侵扰中原&#xff0c;并先后建立多个少数民族政权&#xff0c;又称“五胡乱华”。“五胡”主要指匈奴、鲜卑、羯、羌、氐五个胡人…

第三方app_为什么第三方APP不能下载呢?

这些年科学技术发展日新月异&#xff0c;信息技术和网络技术也层出不穷&#xff0c;大众出行工具的汽车电器化集成度越来越高&#xff0c;汽车上娱乐主机的智能化和网络化程度也越来越高&#xff0c;汽车娱乐主机也成了人民除手机外的第二个娱乐工具&#xff0c;用惯了手机娱乐…

WPF效果第一百九十七篇之Path范围内拖拽

前面效果中分享了彩色马蹄图的效果;这不今天再次在马蹄图的基础上,实现只能在Path内的拖拽效果;闲话不多扯直接看效果:1、关于拖拽顶点实现色域范围选择,参考:https://www.codeproject.com/Tips/828310/The-simplest-WPF-diagram-designer-part2、通过Blend绘制了色度图中间区域…

PHP面向对象常见的关键字和魔术方法

在PHP5的面向对象程序设计中提供了一些常见的关键字&#xff0c;用来修饰类、成员属性或成员方法&#xff0c;使他们具有特定的功能&#xff0c;例如final、static、const等关键字。还有一些比较实用的魔术方法&#xff0c;用来提高类或对象的应用能力&#xff0c;例如__call()…

如何在论文中自动生成标准的参考文献格式

首先下载EndNote软件&#xff0c;word中会自动显示EndNote选项 选择EndNote 选择导出会下载一个txt文件 打开EndNote中向下的箭头导入&#xff08;从文件导入文献到库中&#xff09;找到刚才下载的txt文件 点击选择按键找到txt文件 选择打开即可 选择导入 选择导入的内容…

PrincetonAlgorithm I - Assignment2 Deques and Randomized Queues

Programming Assignment2 - Deque and Randomized Queues Review Assignment Specification 课程笔记 Subtext: Modular Programming Stacks and Queues are fundamental data types Value: collection of objectsBasic Operation: insert, remove, iterate.Difference: which …

TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—基础知识篇...

最近遇到一个线上报警&#xff1a;服务器出现大量TIME_WAIT导致其无法与下游模块建立新HTTP连接&#xff0c;在解决过程中&#xff0c;通过查阅经典教材和技术文章&#xff0c;加深了对TCP网络问题的理解。作为笔记&#xff0c;记录于此。 备注&#xff1a;本文主要介绍…

开源许可证,欢迎来到云时代

出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013)作者 | 唐建法前言开源许可证从最早的 GPL 开始&#xff0c; 逐渐演进到 GPLv2 和 v3&#xff0c;中间还有 Apache、MPL、AGPL、LGPL 等&#xff0c;但是近几年来有一批新的许可证的出现&#xff0c;引起了社区的一些…

selenium - Select类 - 下拉框

WebDriver提供了Select类来处理下拉框。 如百度搜索设置的下拉框&#xff0c;如下图&#xff1a; from selenium import webdriver from selenium.webdriver.support.select import Select from time import sleepdriver webdriver.Chrome() driver.implicitly_wait(10) drive…