要实现自定义自定义标签扩展,需要有如下步骤(在spring中定义了两个接口NamespaceHandler、BeanDefinitionParser,用来实现扩展)

  1.设计配置属性和JavaBean,编写XSD文件;

  2.NamespaceHandler注册一堆BeanDefinitionParser,利用它们来进行解析;

  3.BeanDefinitionParser用于解析每个element的内容;

  4.编写Spring.handlers和Spring.schemas文件以供Spring读取;Spring默认会加载jar包下的META-INF/spring.handlers文件寻找对应的NamespaceHandler;

  Dubbo中Spring扩展就是使用Spring的自定义类型,所以同样也有NamespaceHandler、BeanDefinitionParser

  org.apache.dubbo.config.spring.schema.DubboNamespaceHandler

  

  org.apache.dubbo.config.spring.schema.DubboBeanDefinitionParser

  

  org.apache.dubbo.config.spring.schema.DubboNamespaceHandler#init,该方法用于注册BeanDefinitionParser的实现类,DubboBeanDefinitionParser把不同的配置分别转化成Spring容器中的Bean对象(Config对象);

@Override
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
}

  

  对应的Bean

  

  在Spring启动解析相应的配置标签时,相应的启动provider发布服务注册服务,而同时让consumer在启动的时候自动订阅发现服务,加入了两个Bean, ServiceBean、ReferenceBean,分别继承ServiceConfig和ReferenceConfig;同时还分别实现了InitializingBean、DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware接口;

  InitializingBean:为Bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是实现该接口的类,在初始化Bean的时候会执行该方法;

  DisposableBean :Bean被销毁的时候,spring容器会自动执行destory方法,比如释放资源

  ApplicationContextAware: 实现了这个接口的Bean,当Spring容器初始化的时候,会自动的将ApplicationContext注入进来;

  ApplicationListener :ApplicationEvent事件监听,Spring容器启动后会发一个事件通知;

  BeanNameAware :获得自身初始化时,本身的Bean的id属性;

  下面根据Spring提供接口仿写一个自定义xml标签扩展

  BeanDefinitionParser 用于标签解析

/**
* 用于标签解析
*/
public class BeanDefinitionParser extends AbstractSingleBeanDefinitionParser { @Override
protected Class<?> getBeanClass(Element element) {
return CommonBean.class;
} @Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String id = element.getAttribute("id");
String beanName = element.getAttribute("beanName");
String createTime = element.getAttribute("createTime"); if (StringUtils.hasText(id)) {
builder.addPropertyValue("id", id);
} if (StringUtils.hasText(beanName)) {
builder.addPropertyValue("beanName", beanName);
} if (StringUtils.hasText(createTime)) {
builder.addPropertyValue("createTime", createTime);
}
}
}

  

  BeanNamespaceHandler调用标签解析处理

/**
* 调用标签解析处理
*/
public class BeanNamespaceHandler extends NamespaceHandlerSupport { @Override
public void init() {
// 将节点名与解析类映射,当节点名称为bean,使用BeanDefinitionParser进行解析
registerBeanDefinitionParser("bean", new BeanDefinitionParser());
}
}

  

  

  自定义标签配置,需要在META-INF下创建两个默认Spring配置文件来提供支持,一个是spring.schemas,另一个是spring.handlers,前者是为了验证自定义的xml配置文件是否符合要求,后者是定义Spring解析的配置文件

  

  spring.handlers

http\://org.example/schemas/bean=com.example.bean.schema.BeanNamespaceHandler

  

  spring.schemas

http\://org.example/schemas/bean.xsd=META-INF/bean.xsd

  

  定义一个与自定义配置标签相对应的JavaBean,可根据需要是否实现InitializingBean,ApplicationContextAware等接口

public class CommonBean implements InitializingBean, ApplicationContextAware {
protected String id;
protected String beanName;
protected String createTime;
private transient ApplicationContext applicationContext; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getBeanName() {
return beanName;
} public void setBeanName(String beanName) {
this.beanName = beanName;
} public String getCreateTime() {
return createTime;
} public void setCreateTime(String createTime) {
this.createTime = createTime;
} @Override
public void afterPropertiesSet() {
System.out.println(applicationContext.getBeansOfType(this.getClass()));
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} @Override
public String toString() {
return "CommonBean{" +
"id='" + id + '\'' +
", beanName='" + beanName + '\'' +
", creteTime='" + createTime + '\'' +
'}';
}
}

  

  

  创建一个工程进行测试

  在resources目录下创建bean.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:customer="http://org.example/schemas/bean"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://org.example/schemas/bean http://org.example/schemas/bean.xsd">
<customer:bean id="user" beanName="test1" createTime="2020-08-12"/>
</beans>

  

  测试类

public class MyTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
context.start();
}
}

  

 

dubbo-config-spring自定义xml标签扩展的更多相关文章

  1. spring自定义xml标签&自定义注解

    public class YafBeanDefinitionParser implements BeanDefinitionParser { private BeanDefinitionRegistr ...

  2. 6.2 dubbo在spring中自定义xml标签源码解析

    在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ...

  3. Dubbo源码-Dubbo是如何随心所欲自定义XML标签的

    叨叨 今天考虑了很久要不要写这篇文章. 距离<Dubbo源码>系列的开篇到现在已经快两个月时间了.当时是想着工作上的RPC框架使用存在一些让人头疼的问题,就来看看Dubbo给出了一套什么样 ...

  4. 6.1 如何在spring中自定义xml标签

    dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...

  5. dubbo源码之一——xml schema扩展

    dubbo源码版本:2.5.4 dubbo-parent |----dubbo-config |----dubbo-config-api |----com.alibaba.dubbo.config.* ...

  6. spring整合mybatis错误:class path resource [config/spring/springmvc.xml] cannot be opened because it does not exist

    spring 整合Mybatis 运行环境:jdk1.7.0_17+tomcat 7 + spring:3.2.0 +mybatis:3.2.7+ eclipse 错误:class path reso ...

  7. Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/config/spring/applicationContext.xml]

    在搭建SpringMVC框架的时候遇到了这个问题 问题的原因: 就是没有找到applicatoincontext.xml这个文件, 因为idea自动生成的路径不正确 因此需要再web.xml里面, ( ...

  8. Error creating bean with name 'sqlSessionFactory' defined in class path resource [config/spring/applicationContext.xml]: Invocation of init method failed;

    我报的错: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSes ...

  9. Spring源码阅读笔记05:自定义xml标签解析

    在上篇文章中,提到了在Spring中存在默认标签与自定义标签两种,并且详细分析了默认标签的解析,本文就来分析自定义标签的解析,像Spring中的AOP就是通过自定义标签来进行配置的,这里也是为后面学习 ...

随机推荐

  1. 鸿蒙真的是套壳吗?HarmonyOS应用开发初体验,Java原生和JavaScript的mvvm开发

    初探寻鸿蒙os的应用开发 本期视频已发布到bilibili 注意是应用开发,没错码农(应用开发)一般关注这个就行了 IDE 点击应用开发以后,点击链接下载IDE,DevEco Studio是基于IDE ...

  2. node 进阶 | 通过node中如何捕获异常阐述express的特点

    node如何捕获异常 node基于js的单线程,有了非阻塞异步回调的概念,但是在处理多个并发连接时,并发环境要求高,最重要的是单线程,单核CPU,一个进程crash则web服务都crash,但是为什么 ...

  3. C语言汇总2

    (10-15) 注释:1.单行注释可以嵌套单行注释 eg .//lalalal//lalalal(/后面都是注释完的) 2.多行注释可以嵌套单行注释 (两个**之间的都是注释的) 3.单行注释可以嵌套 ...

  4. matlab中矩阵的表示与简单操作

    原文地址为:matlab矩阵的表示和简单操作 一.矩阵的表示在MATLAB中创建矩阵有以下规则: a.矩阵元素必须在”[ ]”内: b.矩阵的同行元素之间用空格(或”,”)隔开: c.矩阵的行与行之间 ...

  5. MyBatis学习(三)日志输出环境配置

    一.编写日志输出环境配置文件 在开发过程中,最重要的就是在控制台查看程序输出的日志信息,在这里我们选择使用 log4j 工具来输出: 准备工作:将[MyBatis]文件夹下[lib]中的 log4j ...

  6. Centos-显示开机信息-dmesg

    dmesg 显示开机信息,开机时内核将开机信息存储在系统缓冲区(ring buffer)中,存储在 /var/log/dmesg文件中

  7. osgEarth使用笔记1——显示一个数字地球

    目录 1. 概述 2. 实现 2.1. 三维显示 2.2. 二维显示 1. 概述 osgEarth支持.earth格式的文件,里面保存了数字地球相关信息的配置XML,只需要读取这个配置文件,就可以直接 ...

  8. 开源后台系统*mee-admin*

    mee-admin开源后台系统 Preface 这是一个开放的时代,我们不能总是把东西揣在口袋里面自己乐呵. 也正如名言所说的"如果你有两块面包,你当用其中一块去换一朵水仙花" 所 ...

  9. 【题解】[USACO09NOV]A Coin Game S

    Link \(\text{Solution:}\) 菜鸡自己想出来了状态设计,但是没有实现出来--菜死了 设\(dp[i][j]\)表示该选第\(i\)个,最多选\(j\)个的最优解.注意这里的定义仅 ...

  10. K-DTree入门

    \(K-D Tree\),一种用来维护\(K\)维数据的数据结构.常用于维护各种高维的数据,或者是邻近搜索等.从另一种意义上说,实际上就是高维的二叉搜索树.对于一些常见的问题,如\(k\)远点对.三位 ...