Spring自定义标签
如果要开发一个spring自定义的标签比如:
<pre:strategy id="strategyFrist" interface="org.test.spring.schema.strategy.FristStrategy" url="tcp://strategy/frist" />
扩展Spring自定义标签大致需要如下几步:
- 创建需要扩展的组件
- 定义XSD文件描述组件内容
- 创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
- 创建Handler文件,扩展字NamespaceHandlerSupport,目的是将组件注册到Spring容器
- 编写Spring.handlers和Spring.schemas文件
具体步骤如下:
1、创建maven工程spring-schema,添加spring相应jar包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> <optional>true</optional> </dependency>
2、创建一个bean,接收自定义标签属性,如StrategyBean,这里实现了FactoryBean接口,为了将自定义的标签解析完成后注入spring容器
public class StrategyBean implements FactoryBean<Object>{ private String id; private String url; private Class<?> interfaceName; @Override public Object getObject() throws Exception { return interfaceName.newInstance(); } @Override public Class<?> getObjectType() { return interfaceName; } @Override public boolean isSingleton() { return true; } //省略get/set方法 }
3、在工程的META-INF文件夹下定义一个XSD文件描述组件内容,如src/main/resources/META-INF/strategy.xsd
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.shijun.com/schema/strategy" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="strategy"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute type="xs:string" name="id" use="required"/> <xs:attribute type="xs:anySimpleType" name="interface" use="required"/> <xs:attribute type="xs:string" name="url" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> </xs:schema>
4、实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义,如StrategyBeanDefinitionParser
/** * 配置解析器 * @author shijun03 */ public class StrategyBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{ @Override protected Class<?> getBeanClass(Element element) { return StrategyBean.class; } @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String id = element.getAttribute("id"); String url = element.getAttribute("url"); String interfaceName = element.getAttribute("interface"); if(StringUtils.hasText(id)){ //判断bean是否已经注册 boolean hasRegistry = parserContext.getRegistry().containsBeanDefinition(id); if(hasRegistry){ throw new IllegalArgumentException("bean has registry ,please check bean ,id = "+id); } builder.addPropertyValue("id", id); } if(StringUtils.hasText(url)){ builder.addPropertyValue("url", url); } if(StringUtils.hasText(interfaceName)){ Class<?> forName; try { forName = Class.forName(interfaceName); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("interface class not found", e); } builder.addPropertyValue("interfaceName", forName); } } }
5、 创建Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器中,如StrategyBeanHandler
/** * 解析器注入 * @author shijun03 */ public class StrategyBeanHandler extends NamespaceHandlerSupport{ @Override public void init() { registerBeanDefinitionParser("strategy", new StrategyBeanDefinitionParser()); } }
6、编写Spring.handlers和Spring.schemas文件
路径:src/main/resources/META-INF/Spring.handlers
http\://www.shijun.com/schema/strategy=com.sjz.spring.schema.StrategyBeanHandler
路径:src/main/resources/META-INF/Spring.schemas
http\://www.shijun.com/schema/strategy.xsd=META-INF/strategy.xsd
7、创建测试配置文件
新建spring工程,引入前面创建的工程jar以及其他的jar
<dependency> <groupId>com.sjz</groupId> <artifactId>spring-schema</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> //…省略其他的jar
创建FristStrategy对象
public class FristStrategy { public String hello(){ return "hello schema"; } }
在src/main/resources下添加配置文件,如下spring-strategy.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:pre="http://www.shijun.com/schema/strategy" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.shijun.com/schema/strategy http://www.shijun.com/schema/strategy.xsd"> <pre:strategy id="strategyFrist" interface="org.test.spring.schema.strategy.FristStrategy" url="tcp://strategy/frist" /> </beans>
通过Configuration注解引入spring-strategy.xml配置文件
@Configuration @ImportResource(locations="spring-strategy.xml") public class StrategyConfig { }
测试
@SpringBootApplication public class App { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(App.class, args); FristStrategy bean = context.getBean(FristStrategy.class); System.out.println("数据调用结果集========"+bean.hello()); } }
输出如下
数据调用结果集========hello schema
8、详细代码
spring自定义标签工程:https://github.com/ejshi/spring-schema.git 测试工程:https://github.com/ejshi/es/tree/master/test-spring-schema
上一篇: MYSQL常用日期时间函数
下一篇: Java读写Xml