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

一 编写模型类

 package com.hulk.testdubbo.model;

 public class Hero {
private String name;
private int age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}

二 定义xsd文件

 <xsd:schema
xmlns="http://hulk.com/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://hulk.com/schema">
<xsd:complexType name="elementname1complexType">
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The elementname1 name. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="age" type="xsd:int">
<xsd:annotation>
<xsd:documentation><![CDATA[ The elementname1 age. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType> <xsd:element name="elementname1" type="elementname1complexType">
<xsd:annotation>
<xsd:documentation><![CDATA[ elementname1的文档 ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:schema>

说明:

  • 定义targetNamespace(目标命名空间),xmlns的值要与这个相同
  • xsd:element定义的就是将来会在xml文件中用到的元素,例如<dubbo:application>中的application
  • xsd:attribute定义的就是模型类中的属性,例如<dubbo:application name="xxx">中的name,并且可以指定属性类型,进而起到检测的作用(当我们定义的是int,如果在xml中的值是非int型的,直接会报错)。

三 编写spring.schemas

作用:该文件用来指定xsd文件的位置。

http\://hulk.com/schema/hero.xsd=META-INF/hero.xsd

注意:红色部分要与xsd文件中的targetNamespace相同。

四 编写BeanDefinition解析器

作用:主要用来解析自定义的xml标签。

 package com.hulk.testdubbo.schema;

 import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element; public class HeroBeanDefinitionParser implements BeanDefinitionParser {
private final Class<?> beanClass; public HeroBeanDefinitionParser(Class<?> beanClass) {
this.beanClass = beanClass;
} public BeanDefinition parse(Element element, ParserContext parserContext) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(beanClass);
beanDefinition.setLazyInit(false);
beanDefinition.getPropertyValues().add("name", element.getAttribute("name"));
beanDefinition.getPropertyValues().add("age", element.getAttribute("age"));
BeanDefinitionRegistry beanDefinitionRegistry = parserContext.getRegistry();
beanDefinitionRegistry.registerBeanDefinition(beanClass.getName(),beanDefinition);//注册bean到BeanDefinitionRegistry中
return beanDefinition;
}
}

五 编写命名空间处理器

作用:主要用来注册BeanDefinition解析器。

 package com.hulk.testdubbo.schema;

 import com.hulk.testdubbo.model.Hero;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class HeroNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("elementname1", new HeroBeanDefinitionParser(Hero.class));
}
}

说明:通常为每一个xsd:element都要注册一个BeanDefinitionParser。

六 编写spring.handlers文件

作用:主要用于关联命名空间处理器和xsd中的targetNamespace。

http\://hulk.com/schema=com.hulk.testdubbo.schema.HeroNamespaceHandler

说明:key是xsd文件中的targetNamespace。

七 测试 - 编写hero.xml

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hero="http://hulk.com/schema"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://hulk.com/schema http://hulk.com/schema/hero.xsd">
<hero:elementname1 name="xiaona" age="18"/>
</beans>

说明:

  • xmlns:hero的value是xsd文件中的targetNamespace。
  • xmlns:hero可以写成xmlns:xxx,此时<hero:elementname1/>就要写成<xxx:elementname1/>

八 测试 - 编写测试主类

 package com.hulk.testdubbo.test;

 import com.hulk.testdubbo.model.Hero;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("hero.xml");
Hero hero = (Hero) applicationContext.getBean(Hero.class.getName());
System.out.println("name: " + hero.getName() + " age: " + hero.getAge());
}
}

如何在spring中自定义xml标签的方法就结束了。在实际中,随着注解和javaconfg的盛行,xml的方式渐渐的会淡出舞台,但是spring的启动流程还是会的。来看一下上述代码涉及到的流程。

  • 使用ResourceLoader将配置文件xml装载为Resource对象;
  • 使用BeanDefinitionReader解析配置信息:将每一个<bean>解析为一个BeanDefinition对象,然后存储到BeanDefinitionRegistry中
    • 实际上是BeanDefinitionReader调用BeanDefinitionParser进行了解析操作,解析完成后注册到BeanDefinitionRegistry(代码看上边的HeroBeanDefinitionParser)

6.1 如何在spring中自定义xml标签的更多相关文章

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

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

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

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

  3. web.xml中配置Spring中applicationContext.xml的方式

    2011-11-08 16:29 web.xml中配置Spring中applicationContext.xml的方式 使用web.xml方式加载Spring时,获取Spring applicatio ...

  4. ssh整合思想初步 struts2与Spring的整合 struts2-spring-plugin-2.3.4.1.jar下载地址 自动加载Spring中的XML配置文件 Struts2下载地址

    首先需要JAR包 Spring整合Structs2的JAR包 struts2-spring-plugin-2.3.4.1.jar 下载地址 链接: https://pan.baidu.com/s/1o ...

  5. Winform中自定义xml配置文件后对节点进行读取与写入

    场景 Winform中自定义xml配置文件,并配置获取文件路径: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100522648 ...

  6. Spring 框架的概述以及Spring中基于XML的IOC配置

    Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...

  7. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

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

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

  9. dubbo-config-spring自定义xml标签扩展

    要实现自定义自定义标签扩展,需要有如下步骤(在spring中定义了两个接口NamespaceHandler.BeanDefinitionParser,用来实现扩展) 1.设计配置属性和JavaBean ...

随机推荐

  1. 那些年我们踩过的坑之表单reset

    开发者往往是在一个又一个的坑中成长起来的,自学的开发者尤其如此,刚刚填完一个坑,转身又掉进另一个坑.有些坑很容易就跳出来了,也有些坑能整了一天都没头绪,第二天早上一来发现后面就有一架通往坑外的梯子,坑 ...

  2. poj-2421-最小生成树刷题

    title: poj-2421-最小生成树刷题 date: 2018-11-20 20:30:29 tags: acm 刷题 categories: ACM-最小生成树 概述 做了几道最小生成树的题, ...

  3. WatermarkMaker

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Dr ...

  4. bzoj3111: [Zjoi2013]蚂蚁寻路

    题目链接 bzoj3111: [Zjoi2013]蚂蚁寻路 题解 发现走出来的图是一向上的凸起锯齿状 对于每个突出的矩形dp一下就好了 代码 /* */ #include<cstdio> ...

  5. 20172308《Java软件结构与数据结构》第四周学习总结

    教材学习内容总结 第 6 章 列表 一. 列表集合 列表集合:一种概念性表示法,思想是使事物以线性列表的方式进行组织 特点: 列表集合没有内在的容量大小,它可以随着需要而增大 列表集合更具一般化,可以 ...

  6. 使用Newlife网络库管道模式解决数据粘包(二)

    上一篇我们讲了 如何创建一个基本的Newlife网络服务端 这边我们来讲一下如何解决粘包的问题 在上一篇总我们注册了Newlife的管道处理器 ,我们来看看他是如何实现粘包处理的 svr.Add< ...

  7. 如何利用JS判断当前来路域名并跳转到指定页面

    1.如何利用JS判断当前来路域名并跳转到指定页面 获取当前请求路径var href = location.href ;if(href.indexOf("baidu")>-1) ...

  8. C#实现路由器断开连接,更改公网ip

    publicstaticvoid Disconnect() { string url ="断 线";    string uri ="http://192.168.1.1 ...

  9. 微软为何选择在 Github 上开源 .NET 核心?

    本文来自微软开源.NET 的一篇公告 ,文中阐述了微软为何选择在 Github 开源.NET,以及微软对开源和开源社区方面的认识的变迁. 对于.NET来说,今天(2014/11/12)是个大日子! 我 ...

  10. 通过进程ID获取基地址

    下面代码是通过进程ID来获取进程的基地址,创建一个进程快照后,读取进程模块,一般情况下第一个模块就是进程的基地址,下面的程序通过模块的字符串匹配来找到基地址.通过MODULEENTRY32来读取,下面 ...