微服务框架开发(二)—扩展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,一经查实,立即删除!

相关文章

Linux下下载JDK

需要加特殊的前缀,不然无法下载文件 . 例如JDK8 U131 wget -c --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz转载于:https://w…

如何找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;结果趋于零…

实现简单的shell sed替换功能

1 import sys2 3 fopen(lyrics.txt,r,encodingutf-8) #读写4 f_newopen(lyrics_new,w,encodingutf-8)5 find_strsys.argv[1]6 replace_strsys.argv[2]7 for line in f:8 if find_str in line:9 lineline.replace(find_str,replace_str) 10 f_new.write(line) …

开源新工具 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…

oracle 修改sgamaxsize_oracle初始化内存配置参数(sga,pga,sharepool)

小白在日常工作中经常遇到数据库启动报错&#xff0c;其中80%都是跟数据库的初始化内存参数有关&#xff0c;现整理一份模板&#xff0c;以期后用1. 查出linux服务器总的内存&#xff1a;8G左右integer memTotalSizegrep ^MemTotal: /proc/meminfo | awk {print $2} 8064956…

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

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

用PHP去掉文件头的Unicode签名(BOM)

<?php //此文件用于快速测试UTF8编码的文件是不是加了BOM&#xff0c;并可自动移除 //By Bob Shen $basedir"."; //修改此行为需要检测的目录&#xff0c;点表示当前目录 $auto1; //是否自动移除发现的BOM信息。1为是&#xff0c;0为否。 //以下不用改动 if ($dh…

VMware虚拟机12安装linux系统

http://jingyan.baidu.com/article/4f7d5712d20a1b1a21192760.html 阿里云开源镜像站&#xff1a;http://mirrors.aliyun.com/转载于:https://www.cnblogs.com/liuxinfei/p/6139921.html

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

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

基于 Filter 实现条件路由

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

CentOS 6.9通过RPM安装EPEL源(http://dl.fedoraproject.org)

另类的装法&#xff0c;通过RPM包直接安装 wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm && rpm -ivh epel-release-6-8.noarch.rpm 可以发现上面的地址可以找到非6以外的包&#xff08;http://dl.fedoraproject.org&#xff09;

虚拟机防火墙

1.即时生效&#xff0c;重启后失效 开启&#xff1a;service iptables start 关闭&#xff1a;service iptables stop 2 重启后生效 开启&#xff1a;chkconfig iptables on 关闭&#xff1a;chkconfig iptables off 注意&#xff1a;需要用root用户执行此操作转载于:https://w…

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

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

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

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

如何在Jupyter Notebook中使用在anaconda中创建的虚拟环境

如何在Jupyter Notebook中使用在anaconda中创建的虚拟环境 1、创建虚拟环境并激活 conda create -n 虚拟环境名 python 3.8 conda activate 虚拟环境名 2、在虚拟环境中安装ipykernel pip install ipykernel 使用ipykernel生成虚拟环境的kernel python -m ipykernel insta…

BZOJ1823:[JSOI2010]满汉全席——题解

https://www.lydsy.com/JudgeOnline/problem.php?id1823 https://www.luogu.org/problemnew/show/P4171 题面太长啦就不粘过来啦&#xff01; 裸的2-SAT用来练板子的。 显然属于“a和b之间必须选一种”模型&#xff0c;只要a向b连边&#xff0c;b向a连边即可。 &#xff08;被…