Spring中xml自定义标签的实现流程
Spring中xml自定义标签的实现流程
背景:
虽然xml方式在现在看来有一些落后了,但毕竟是注解的一种过渡。而解析器不管是注解还是xml都是一致的。
例如:dubbo大量的自定义标签,包括spring中也存在大量的标签(低版本xml方式),那么自定义标签在Spirng中是如何实现的,今天就来理一下流程。
一、实现步骤先知
- 编写一个XSD: 定义需要使用到的标签
- 编写一个解析标签的BeanDefinitionParse: 解析这些标签,将会做什么操作
- 编写一个Handler,将自定义的BeanDefinitionParse进行注册: 将其注册到Map集合中。
- 编写spring.handlers 和 spring.schemas 两个文件:分别告诉handler 和 schema的位置。
- 编写一个应用程序验证
二、自定义标签实现
模拟<context:component-scan/>
实现注解扫描操作;实现标签<uzong:component-scan/>
话不多说,直接开始吧
工程结构如下:
2.1 编写xsd
模拟context,编写一份自己的xsd。名称:uzong.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/uzong"
elementFormDefault="qualified">
<xsd:element name="component-scan">
<xsd:complexType>
<xsd:attribute name="base-package" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma/semicolon/space/tab/linefeed-separated list of packages to scan for annotated components.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>
关键元素:base-package
;指定路径包名
2.2 编写自己的parse
下面的代码主要逻辑就是获取basePackage路径,然后使用ClassPathBeanDefinitionScanner
进行扫描注解。关于扫描器的使用不是本篇重点,可以跳过。
public class UzongComponentScanBeanDefinitionParse implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//1. 获取value
String basePackage = element.getAttribute("base-package");//仅解析:base-package
//2. 解析获取basePackage
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
// 3. 字符串分割
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
//4. 获取扫描器
ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), true);
//5. 扫描注册
scanner.scan(basePackages);
return null;
}
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
readerContext.getEnvironment(), readerContext.getResourceLoader());
}
}
在完成了我们的parse后,需要编写Handler来注册parse到Spring的集合中
2.3 注册handler 到集合
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class UzongContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("component-scan",new UzongComponentScanBeanDefinitionParse());
}
}
registerBeanDefinitionParser 实质就是将其放入map中;NamespaceHandlerSupport 中的parsers
2.4 spring.handlers 和 spring.schemas
spring.handlers
http\://www.springframework.org/schema/uzong=uzong.parse.UzongContextNamespaceHandler
spring.schemas
http\://www.springframework.org/schema/uzong.xsd=META-INF/uzong.xsd
完成上面步骤后,基本上已经完成自定义标签的实现流程了,接下进行验证
2.5 验证
编写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:uzong="http://www.springframework.org/schema/uzong"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/uzong http://www.springframework.org/schema/uzong.xsd">
<uzong:component-scan base-package="uzong.parse"/>
</beans>
其中Apple 为一个bean
@Component
public class Apple {
private String name = "apple";
public Apple() {
}
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
'}';
}
public Apple(String name) {
this.name = name;
}
}
public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("application-uzong.xml");
// 从容器中获取bean
Apple apple = (Apple) ac.getBean("apple");
System.out.println(apple);
}
}
运行结果如下:
Apple{name='apple'}
2.6 小结
通过以上几个步骤,就完成了自定义标签的实现流程。不过这种xml的方式是否已经比较过时了;现在多采用注解方式。但是,注解和xml的解析本质都是一样的。重点都是在parse这个类上面。
上一篇: HDFS安装使用详解
下一篇: HDFS编程实践
推荐阅读
-
Spring中xml自定义标签的实现流程
-
java实现利用String类的简单方法读取xml文件中某个标签中的内容
-
java实现利用String类的简单方法读取xml文件中某个标签中的内容
-
使用jsp自定义标签库实现数据列表显示模拟cms4j中的标签库效果
-
Spring Data MongoDB中实现自定义级联的方法详解
-
解析在Android中为TextView增加自定义HTML标签的实现方法
-
解析在Android中为TextView增加自定义HTML标签的实现方法
-
Android实现在xml文件中引用自定义View的方法分析
-
Android实现在xml文件中引用自定义View的方法分析
-
Spring中的自定义标签