Dubbo基于自定义配置,实现自己的Bean。

通常,完成一个自定义配置需要以下步骤:

  • 设计配置属性和JavaBean;
  • 编写XSD文件;
  • 编写NamespaceHandler和BeanDefinitionParser完成解析工作;
  • 编写spring.handlers和spring.schemas串联起所有部件;
  • 在Bean文件中应用。

下面是一个小Demo,

(1)设计配置属性和JavaBean

首先当然得设计好配置项,并通过 JavaBean 来建模,本例中需要配置 People 实体,配

置属性 name 和 age(id 是默认需要的)

  1. public class People {
  2. private String id;
  3. private String name;
  4. private Integer age;
  5. }

(2)编写 XSD 文件

为上一步设计好的配置项编写 XSD 文件,XSD 是 schema 的定义文件,配置的输入和解

析输出都是以 XSD 为契约,本例中 XSD 如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsd:schema
  3. xmlns="http://blog.csdn.net/cutesource/schema/people" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  4. xmlns:beans="http://www.springframework.org/schema/beans"
  5. targetNamespace="http://blog.csdn.net/cutesource/schema/people" elementFormDefault="qualified"
  6. attributeFormDefault="unqualified">
  7. <xsd:import namespace="http://www.springframework.org/schema/beans"/>
  8. <xsd:element name="people">
  9. <xsd:complexType>
  10. <xsd:complexContent>
  11. <xsd:extension base="beans:identifiedType">
  12. <xsd:attribute name="name" type="xsd:string"/>
  13. <xsd:attribute name="age" type="xsd:int"/>
  14. </xsd:extension>
  15. </xsd:complexContent>
  16. </xsd:complexType>
  17. </xsd:element>
  18. </xsd:schema>

xsd:schema 的各个属性具体含义参考 http://www.w3school.com.cn/schema/schema_schema.asp

<xsd:element name="people">对应着配置项节点的名称,因此在应用中会用 people 作为 节点名来引用这个配置

<xsd:attribute name="name" type="xsd:string" /> 和 <xsd:attribute name="age" type="xsd:int" />对应着配置项people的两个属性名,因此在应用中可以配置name和 age 两个属性,分别是 string 和 int 类型

完成后需把 xsd 存放在 classpath 下,一般都放在 META-INF 目录下(本例就放在这个目录下)。

(3)编写 NamespaceHandler 和 BeanDefinitionParser 完成解析工作

下面需要完成解析工作,会用到 NamespaceHandler 和 BeanDefinitionParser 这两个概念。

具体说来 NamespaceHandler 会根据 schema 和节点名找到某个 BeanDefinitionParser,然后由 BeanDefinitionParser 完成具体的解析工作。因此需要分别完成 NamespaceHandler 和 BeanDefinitionParser 的实现类,Spring 供了默认实现类 NamespaceHandlerSupport 和 AbstractSingleBeanDefinitionParser,简单的方式就是去继承这两个类。本例就是采取这种方式:

  1. import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
  2. public class MyNamespaceHandler extends NamespaceHandlerSupport {
  3. public void init() {
  4. registerBeanDefinitionParser("people", new PeopleBeanDefinitionParser());
  5. }
  6. }

其中 registerBeanDefinitionParser("people", new PeopleBeanDefinitionParser());就是用来 把节点名和解析类联系起来,在配置中引用 people 配置项时,就会用

PeopleBeanDefinitionParser 来解析配置。PeopleBeanDefinitionParser 就是本例中的解析类:

  1. import org.springframework.beans.factory.support.BeanDefinitionBuilder;
  2. import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
  3. import org.springframework.util.StringUtils;
  4. import org.w3c.dom.Element;
  5. public class PeopleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
  6. protected Class getBeanClass(Element element) {
  7. return People.class;
  8. }
  9. protected void doParse(Element element, BeanDefinitionBuilder bean) {
  10. String name = element.getAttribute("name");
  11. String age = element.getAttribute("age");
  12. String id = element.getAttribute("id");
  13. if (StringUtils.hasText(id)) {
  14. bean.addPropertyValue("id", id);
  15. }
  16. if (StringUtils.hasText(name)) {
  17. bean.addPropertyValue("name", name);
  18. }
  19. if (StringUtils.hasText(age)) {
  20. bean.addPropertyValue("age", Integer.valueOf(age));
  21. }
  22. }
  23. }

(4)编写 spring.handlers 和 spring.schemas 串联起所有部件

上面几个步骤走下来会发现开发好的 handler 与 xsd 还没法让应用感知到,就这样放上去是没法把前面做的工作纳入体系中的,spring 供了 spring.handlers 和 spring.schemas 这 两个配置文件来完成这项工作,这两个文件需要我们自己编写并放入 META-INF 文件夹中, 这两个文件的地址必须是 META-INF/spring.handlers 和 META-INF/spring.schemas,spring 会默 认去载入它们。

本例中 spring.handlers 如下所示:

http://blog.csdn.net/cutesource/schema/people=study.schemaExt.MyNamespaceHandler

以上表示当使用到名为"http://blog.csdn.net/cutesource/schema/people"的 schema 引用时, 会通过 study.schemaExt.MyNamespaceHandler 来完成解析

spring.schemas 如下所示:

http://blog.csdn.net/cutesource/schema/people.xsd=META-INF/people.xsd

以上就是载入 xsd 文件。

(5)在 Bean 文件中应用

到此为止一个简单的自定义配置以完成,可以在具体应用中使用了。使用方法很简单, 和配置一个普通的 spring bean 类似,只不过需要基于我们自定义 schema,本例中引用方式

如下所示:

  1. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xmlns:cutesource="http://blog.csdn.net/cutesource/schema/people" xsi:schemaLocation="
  3. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.x sd
  4. http://blog.csdn.net/cutesource/schema/people http://blog.csdn.net/cutesource/schema/people.xsd">
  5. <cutesource:people id="cutesource" name="袁志俊" age="27"/>
  6. </beans>

其中 xmlns:cutesource="http://blog.csdn.net/cutesource/schema/people"是用来指定自定义 schema , xsi:schemaLocation 用 来 指 定 xsd 文 件 。 <cutesource:people id="cutesource" name="zhijun.yuanzj" age="27"/>是一个具体的自定义配置使用实例。

最后就可以在具体程序中使用基本的 bean 载入方式来载入我们的自定义配置对象了, 如:

  1. ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml"); People p = (People)ctx.getBean("cutesource");
  2. System.out.println(p.getId());
  3. System.out.println(p.getName());
  4. System.out.println(p.getAge());

会输出:

cutesource

袁志俊

27

以上就是一个基于 Spring 可扩展 Schema 供自定义配置支持实战过程,一些复杂应用 和技巧还有待挖掘。

Dubbo学习摘录(一)的更多相关文章

  1. Dubbo学习摘录(二)

    扩展点机制 扩展点的配置 (1)根据关键字读取配置,获取具体的实现类 比如在 dubbo-demo-provider.xml 文件中配置: 则会根据rmi去读取具体的协议实现类RmiProtocol. ...

  2. Dubbo学习摘录(零)

    节点角色说明: Provider:暴露服务的服务提供方: Consumer:调用远程服务的服务消费方: Registry:服务注册与发现的注册中心: Monitor: 统计服务的调用次数和调用时间: ...

  3. Dubbo学习小记

    前言 周一入职的新公司,到了公司第一件事自然是要熟悉新公司使用的各种技术,搭建本地的环境. 熟悉新公司技术的过程中,首先就是Maven,这个前面已经写过文章了,然后就是Dubbo----公司的服务都是 ...

  4. dubbo学习(zz)

    dubbo学习 博客分类: 开源软件   Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站 ...

  5. Dubbo学习(六) dubbo 架构图 以及调用过程

    一.Dubbo结构图   duubo结构图 我们解释以下这个架构图:Consumer服务消费者,Provider服务提供者.Container服务容器.消费当然是invoke提供者了,invoke这条 ...

  6. Dubbo学习(一) Dubbo原理浅析

    一.初入Dubbo Dubbo学习文档: http://dubbo.incubator.apache.org/books/dubbo-user-book/ http://dubbo.incubator ...

  7. dubbo学习小结

    dubbo学习小结 参考: https://blog.csdn.net/paul_wei2008/article/details/19355681 https://blog.csdn.net/liwe ...

  8. Dubbo学习系列之十三(Mycat数据库代理)

    软件界有只猫,不用我说,各位看官肯定知道是哪只,那就是大名鼎鼎的Tomcat,现在又来了一只猫,据说是位东方萌妹子,暂且认作Tom猫的表妹,本来叫OpencloudDB,后又改名为Mycat,或许Ca ...

  9. Dubbo学习系列之八(分布式事务之MQ方案)

    自从小王玩起了微服务,发现微服务果然很强大,好处真是太多,心中暗喜,然而,却也遇到了分布式中最棘手的问题:分布式事务.小王遍访各路神仙,也无个完美开源解决方案,当然,也有些实际可行的手法,虽不算完美, ...

随机推荐

  1. Programming a robot

    题目链接:Gym - 101492H 自己的纯暴力做法: /* */ # include <iostream> # include <cstdio> # include < ...

  2. 树莓派从烧录系统到通过wifi远程访问(新树莓派配置,无显示器、网线、键盘)

    本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/raspberry_from_install_to_remote_ ...

  3. django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applie

    Traceback (most recent call last): File "manage.py", line 15, in <module> execute_fr ...

  4. 微信小程序之数据缓存

    关于缓存,举个示例,假定我不是通过微信授权登录的方式,小程序又是如何识别我登录后的身份呢???效果图: 这个功能我是通过缓存实现的. 关键核心代码如下: wx.setStorage({ key: 'u ...

  5. 20189220 余超《Linux内核原理与分析》第四周作业

    构造一个简单的Linux系统MenuOS 第三章基础知识 计算机的三大法宝:存储计算机,函数调用堆栈,中断. 操作系统的两把宝剑:中断上下文,进程上下文. Linux内核源码的目录结构: arch目录 ...

  6. Web前端开发规范之图片命名规范

    图片的名称分为头尾两部分,用下划线隔开,头部表示此图片的大类性质,例如广告,标志,菜单,按钮等 banner:放置在页面顶部的广告,装饰图案等长方形的图片 logo:标志性的图片 button:在页面 ...

  7. 剑指offer:数字在排序数组中出现的次数

    题目描述: 统计一个数字在排序数组中出现的次数. 思路分析: 1. 直观思路是直接遍历一遍,统计.复杂度也只要O(n). 2. 显然这道题要考察的内容不这么简单,实际上考虑二分的思想来完成.分别二分查 ...

  8. 实验与作业(Python)-02 Python函数入门与温度转换程序(函数、input、eval、int、float、列表)

    截止日期 实验目标 学会定义函数,使用函数.学会导入在某个文件中定义的函数. input获得值,然后通过eval或者int.float将其转换为相应的类型. 学会使用列表:访问列表.append.遍历 ...

  9. The fileSyncDll.ps1 is not digitally signed. You cannot run this script on the current system.

    https://www.opentechguides.com/how-to/article/powershell/105/powershel-security-error.html Unblockin ...

  10. mysql性能测试-------重要!!!

    我们在做性能测试的目的是什么,就是要测出一个系统的瓶颈在哪里,到底是哪里影响了我们系统的性能,找到问题,然后解决它.当然一个系统由很多东西一起组合到一起,应用程序.数据库.服务器.中中间件等等很多东西 ...