欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring自定义标签

程序员文章站 2022-05-29 22:47:59
...

    如果要开发一个spring自定义的标签比如: 

<pre:strategy id="strategyFrist" interface="org.test.spring.schema.strategy.FristStrategy"
		url="tcp://strategy/frist" />

    扩展Spring自定义标签大致需要如下几步: 

  1. 创建需要扩展的组件
  2. 定义XSD文件描述组件内容
  3. 创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
  4. 创建Handler文件,扩展字NamespaceHandlerSupport,目的是将组件注册到Spring容器
  5. 编写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

 

 

相关标签: spring xml