Spring源码阅读之编写自定义标签

基于昨天的那篇文章,我们今天来聊一个比较简单轻松点的话题,今天我们来实现一个自定义的标签。

(本文来自公众号:z小赵)
先明确下整个项目的结构,网上有很多关于自定义标签的实现方式,但是教程包结构不清晰,导致测试无法正常进行,博主自己也栽了一个坑,为了让朋友们可以快速验证结果,我们首先来介绍一下包结构。

第一个工程包结构,该工程的作用是为了实现一个自定义标签。

第二个工程是为了验证自定义标签是否能够正常工作。

这里说一下为什么创建了两个工程,博主就是在这里遇到了一个坑,最开始博主在一个工程下实现了标签并且去做验证,遇到了一个比较怪异的报错,如下,大概意思就是说 'mytag:annotation' 找不到,苦思冥想命名定义了为什么会找不到呢?朋友们混个眼熟,后面会讲为啥。

Caused by: org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 42; cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'mytag:annotation' 的声明。at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)at

  1. 清楚了包结构,我们先来介绍第一个工程涉及文件的作用
  • MyNamespaceDefinitionParse:用于解析标签的具体实现
  • MyNamespaceHandler:命名空间处理器,用于注册标签对应的解析器
  • MyTagBean:自定义BeanClass
  • spring.handlers:指定使用的命名空间处理器,即指定MyNamespaceHandler
  • spring.schemas:用于指定.xsd文件位置的
  • resource-1.0.xsd:用于定义标签,也可理解成规范标签编写规则的
  1. 我们先来介绍下resource-1.0.xsd文件内容。
<?xml version="1.0" encoding="UTF-8"?>

  1. spring.schemas文件内容如下,用于指定resource-1.0.xsd文件的位置,左边为 key,右边为该文件在本地的位置,如果该文件在本地找不到会尝试去远程去找,即左边 key 指定的远程位置去获取。
http://www.zxz.com/resource/resource-1.0.xsd=/resource-1.0.xsd

  1. spring.handlers文件内容如下,用于指定自定义标签的解析器位置,左边为 key,右边为该文件在本地的位置。
http://www.zxz.com/resource=com.zxz.resource.MyNamespaceHandler

  1. MyTagBean.java文件,设置了 name myPackage两个属性,注意这个字段名和resource-1.0.xsd文件定义的名字实际上没有什么直接联系,只是名字相同而已。
package com.zxz.resource;/*** @author zxz*/public class MyTagBean {    private String name;    private String myPackage;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getMyPackage() {        return myPackage;    }    public void setMyPackage(String myPackage) {        this.myPackage = myPackage;    }    @Override    public String toString() {        return "MyTagBean{" + "name='" + name + ''' + ", myPackage='" + myPackage + ''' + '}';    }}

  1. MyNamespaceHandler.java文件内容如下,其继承了NamespaceHandlerSupport,实现了init方法。用于注册具体annotation 标签对应的解析器,这个和上次讲的的做法是一样的,不熟悉的朋友可以先看上一讲。
package com.zxz.resource;import org.springframework.beans.factory.xml.NamespaceHandlerSupport;/** * @author zxz */public class MyNamespaceHandler extends NamespaceHandlerSupport {    public void init() {        registerBeanDefinitionParser("annotation", new MyNamespaceDefinitionParse());    }}

  1. MyNamespaceDefinitionParse.java内容如下,其实现了BeanDefinitionParse接口,来实现parse方法。
package com.zxz.resource;import org.springframework.beans.MutablePropertyValues;import org.springframework.beans.factory.config.BeanDefinition;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;/** * @author zxz */public class MyNamespaceDefinitionParse implements BeanDefinitionParser {    public BeanDefinition parse(Element element, ParserContext parserContext) {        RootBeanDefinition beanDefinition = new RootBeanDefinition();        // 设置beanClass        beanDefinition.setBeanClass(MyTagBean.class);        MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();        // 添加name属性        if (element.hasAttribute("name")) {            mutablePropertyValues.addPropertyValue("name", element.getAttribute("name"));        }        // 添加package属性        if (element.hasAttribute("myPackage")) {            mutablePropertyValues.addPropertyValue("myPackage", element.getAttribute("myPackage"));        }        String id = element.getAttribute("id");        // 拿到注册表, 注册BeanDefinition        parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);        return beanDefinition;    }}

至此,我们的自定义标签就制作完成了,接下来打成 jar 包,在第二个测试工程中进行测试。


  1. 第二个工程文件介绍。
  • applicationContext.xml:编写定义标签内容
  • Test.java:测试方法
  • pom.xml:引入第一个工程的 jar 包

  1. applicationContext.xml文件内容如下,在测试启动的时候会找 http://www.zxz.com/resource/resource-1.0.xsd和http://www.zxz.com/resource对应的.xsd文件和对应的处理器。回答下前面的那个报错原因,因为在 spring 启动的时候会先扫描本地所有的.handlers和.schemas文件,如果本地找不到回去远程找。但是从我们的报错可以看出,应该是没有扫描到我们自定义的两个文件,但是我们将其打成 jar 包,在另外一个工程里引用就可以扫到,所以我猜想 spring 启动只扫描在 pom 文件指定的那些包下文件。
<?xml version="1.0" encoding="UTF-8"?>

  1. Test.xml文件内容如下。
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");        System.out.println(context.getBean("myTagBean"));    }}

11. 运行测试代码,最终输出结果如下。

总结

以上即为创建一个自定义标签的流程,全部代码都经过测试并得出预期结果。

具体的运行原理我在上一篇讲解标签的源码解析讲解过了,不熟悉的朋友先看看上一篇内容。至此,我们关于标签解析成BeanDefinition对象并将其注册到BeanFactory的全部流程就讲完了,涉及到的其他细节朋友大家自行了解,或者可以和我交流。

下一篇文章我们来讲讲下一个比较重要的流程invokeBeanFactoryPostProcessors,希望大家和我继续坚持下去,搞定 Spring 最核心的灵魂。

感谢大家支持,多多转发关注不迷路~~

感谢大家支持~~

java反编译能拿到源码吗_大牛带你解读Spring源码,编写自定义标签,您能学会吗?相关推荐

  1. c++报错:引用了未定义标签_大牛带你解读Spring源码,编写自定义标签,您能学会吗?...

    Spring源码阅读之编写自定义标签 基于昨天的那篇文章,我们今天来聊一个比较简单轻松点的话题,今天我们来实现一个自定义的标签. (本文来自公众号:z小赵) 先明确下整个项目的结构,网上有很多关于自定 ...

  2. 使用java反编译查看java生成的exe文件的源码

    第一次写博客,也些有些问题. 上网下载一个java反编译软件,我使用的是jd-gui这款软件. 在编译时,不能直接用编译软件打开exe执行文件,有些软件是可以打开的,不过显示的是汇编代码. 首先打开e ...

  3. 一些Java反编译工具/源代码查看工具的介绍

    2019独角兽企业重金招聘Python工程师标准>>> 有的朋友抱怨他们在使用他们公司的闭源框架时看不到底层的源代码.那么可以尝试使用一些Java反编译工具. 下面我举个例子介绍具体 ...

  4. eclipse安装JAVA反编译插件

    前言:在实际的开发中几乎都会使用到一些框架来辅助项目的开发工作,对于一些框架的代码我们总怀有一些好奇之心,想一探究竟,有源码当然更好了,对于有些JAR包中的代码我们就需要利用反编译工具来看一下了,下面 ...

  5. Eclipse Class Decompiler——Java反编译插件(转)

    Eclipse Class Decompiler是一款Eclipse插件,整合了多种反编译器,和Eclipse Class Viewer无缝集成,能够很方便的使用插件查看类库源码,进行Debug调试. ...

  6. java反编译工具_Java开发必会的反编译知识(附支持对Lambda进行反编译的工具)...

    我之前推送过Java代码的编译与反编译,其中简单的介绍了Java编译与反编译相关的知识,最近给GitChat写<深入分析Java语法糖>的时候,又用到了很多反编译相关的知识,遂发现哪篇文章 ...

  7. [转]一款可以反编译jar包的java反编译工具-JD-GUI(绿色软件)

    [转]一款可以反编译jar包的java反编译工具-JD-GUI(绿色软件) 文章分类:Java编程 该软件无需安装,界面清爽. 转自:http://www.devdoc.org/index.php/a ...

  8. JAVA反编译工具精选

    ===================================================================== JAVA 语言是 1995 年 5 月由 SUN 公司发布的 ...

  9. JAVA反编译工具总结

    JAVA反编译工具总结 JAVA语言是1995年5月由SUN公司发布的,由于其安全性高.代码优化.跨平台等特性,迅速取代了很多传统高级语言,占据了企业级网络应用开发等诸多领域的霸主地位. 不过,JAV ...

  10. Java 反编译工具的使用与对比分析

    前言 Java 反编译,一听可能觉得高深莫测,其实反编译并不是什么特别高级的操作,Java 对于 Class 字节码文件的生成有着严格的要求,如果你非常熟悉 Java 虚拟机规范,了解 Class 字 ...

最新文章

  1. 下载、安装、配置 java jdk1.8
  2. 基于特征的推荐算法【转】
  3. 【Javascript】 == 、=== 区别
  4. 【机器学习】特征降维
  5. django-正向查找
  6. 如何使用CSS3 Border Radius属性
  7. Angular 学习笔记——拖拽
  8. 昇腾AI处理器软件栈--神经网络软件架构
  9. MTK 驱动开发(28)--6797平台 TP 移植
  10. 学习云计算有哪些优势?云计算教程学习路线图
  11. AI2想从常识测试开始让AI理解物理世界,数据集已公布
  12. 终极解决maya渲染层丢材质,变线框等问题
  13. IDEA——一个项目启动多个服务
  14. 【转】什么是乐观锁,什么是悲观锁
  15. 关于微服务的两篇文章以及Eventuate
  16. 哪些场景N1 mode是disable状态
  17. 最新Java设计模式之美
  18. Qt设计师-提升法(自定义部件)“提升为”
  19. CSS基本知识点整理(一)
  20. Tampermonkey[油猴插件]开发者的神级工具!

热门文章

  1. 《Python硬件编程实战》——1.3 Python的特点
  2. C#程序通过模板自动创建Word文档
  3. oracle 主要语句大荟萃
  4. mysql查询表字段的个数
  5. xampp 运行 yaf框架
  6. Matlab函数——dct2
  7. 全网首发:JDK绘制文字:四、绘制文字的具体函数分析
  8. LINUX下载并编译javasqlite
  9. MAC编译OpenJDK8:ld: library not found for -lstdc++(独家解决办法)
  10. FreeSwitch会议Banner功能调用流程