基于Spring自定义标签
需求:基于Spring自定义标签,实现通过Bean方式来统一时间格式,避免在开发中不同开发者使用的时间格式不一致导致系统难以维护。自定义标签方式如下:
1. 核心配置文件位置如下:
2. 核心配置内容如下:
huhx.xsd
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns="http://www.huhx.com/schema/ch" -->
<xsd:schema xmlns="http://www.huhx.com/schema/ch"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.huhx.com/schema/ch"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<!--
xsd:element 表示定义标签
xsd:extension 如java中的继承,把现有的定义继承进来
xsd:attribute 标签带有的属性
xsd:complexType 元素定义复杂类型
xsd:complexContent 元素定义对复杂类型(包含混合内容或仅包含元素)的扩展或限制。
-->
<xsd:element name="dateformat">
<xsd:complexType>
<xsd:complexContent>
<!-- 继承定义 从namespace="http://www.springframework.org/schema/beans" -->
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="lenient" type="xsd:boolean"/>
<xsd:attribute name="pattern" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
spring.handlers
http\://www.huhx.com/schema/ch=cn.edu.his.pay.handler.MyNamespaceHandler
spring.schemas
http\://www.huhx.com/schema/ch.xsd=META-INF/huhx.xsd
MyNamespaceHandler.java
package cn.edu.his.pay.handler;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MyNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("dateformat", new SimpleDateFormatBeanDefinitionParser());
}
}
SimpleDateFormatBeanDefinitionParser.java
package cn.edu.his.pay.handler;
import java.text.SimpleDateFormat;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
protected Class getBeanClass(Element element) {
return SimpleDateFormat.class;
}
protected void doParse(Element element, BeanDefinitionBuilder bean) {
String pattern = element.getAttribute("pattern");
bean.addConstructorArgValue(pattern);
String lenient = element.getAttribute("lenient");
if (StringUtils.hasText(lenient)) {
bean.addPropertyValue("lenient", Boolean.valueOf(lenient));
}
}
}
spring-dispatcher.xml 标签使用代码(核心部分)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:ch="http://www.huhx.com/schema/ch"
xsi:schemaLocation="
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.huhx.com/schema/ch
http://www.huhx.com/schema/ch.xsd">
<ch:dateformat id="dateFormat" pattern="yyyy-MM-dd HH:mm" lenient="true"/>
</beans>
测试代码如下:
package cn.edu.his.pay.handler;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring/spring-dispatcher.xml");
SimpleDateFormat info = (SimpleDateFormat) context.getBean("dateFormat");
System.out.println("自定义的dateFormat:"+info.format(new Date()));
System.out.println("系统的dateFormat:"+new SimpleDateFormat().format(new Date()));
/*
自定义的dateFormat:2018-05-08 12:38
系统的dateFormat:18-5-8 下午12:38
*/
}
}
@Controller
public class DateformatController {
@Autowired
@Qualifier("dateFormat")
private SimpleDateFormat date;
@ResponseBody
@RequestMapping("/date")
public String date(){
return date.format(new Date());
}
}
4. 总结
通过上面自定义标签的实现,这样我们可以在xml定义不同格式的Bean,通过Bean注入的方式来复用功能代码。只要涉及到代码复用或代码重构,我们也可以考虑使用这种基于xml标签配置方式来做。这里列举的方式比较简单,但不是重点,重点是在对于Spring的架构的扩展机制更加深入的理解。