Spring源码(七):自定义标签

15 篇文章 0 订阅

一.   Spring源码(六):深入自定义标签解析介绍了Spring对自定义标签的解析,这篇文件主要介绍如何自定义标签来完成复杂的业务需求。

二.  先简单回顾一下上篇文件介绍的自定义标签的解析。

        1.  获取所有的NamespaceHandler:

             通过Spring的SPI加载所有jar包META-INF/spring.handlers下的文件,经过反射创建实例化并调用init初始化方法初始化BeanDefinitionParser解析器存入属性parsers中,然后将NamespaceHandler封装到handlerMappings属性中。            

  

        2. 根据namespaceUri(http://oss.housihai.com/schema/reyco)获取到具体的NamespaceHandler,然后调用它的parse()方法。

         3.在parse()方法中先根据标签到parsers属性中获取到具体的BeanDefinitionParser解析类,然后调用BeanDefinitionParser解析类的parse。在parse方法中将标签属性封装到BeanDefinition中,然后注册到Spring容器中。(parsers属性就是我们调用NamespaceHandler的init方法的时候注入的)

   三.  开始自定义标签:

         模拟bean标签注册Bean对象,标签样式如下图:

                id:bean的名称      class:beanClass的类型

        1.  定义META-INF/spring-reyco.xsd文件

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://oss.housihai.com/schema/reyco"
	xmlns:tns="http://oss.housihai.com/schema/reyco"
	elementFormDefault="qualified">

	<element name="reyco">
		<complexType>
			<attribute name="id" type="string"></attribute>
			<attribute name="class" type="string"></attribute>
		</complexType>
	</element>
	
</schema>

       2. 定义一个命名空间处理器NamespaceHandler,继承NamespaceHandlerSupport并重写init方法。

/**
 * @author reyco
 * @version v1.0.1
 */
public class ReycoNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("reyco", new ReycoBeanDefinitionParser());
	}

}

       3.在init方法中需要注册一个BeanDefinitionParser(Bean定义解析器),解析我们的自定义标签。所以需要定义一个BeanDefinitionParser,实现parse方法。

/**
 * element的解析器:
 * 		可以实现@Link(BeanDefinitionParser)接口,也可以继承@Link(BeanDefinitionParser)的子类去实现如:AbstractBeanDefinitionParser、AbstractSingleBeanDefinitionParser
 * 		我这里通过实现了BeanDefinitionParser接口并手动注册了Bean
 * @author reyco
 * @version v1.0.1
 */
public class ReycoBeanDefinitionParser implements BeanDefinitionParser {

	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		String beanClassName = element.getAttribute("id");
		String beanClass = element.getAttribute("class");
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
		AbstractBeanDefinition beanDefinition = builder.getRawBeanDefinition();
		try {
			beanDefinition.setBeanClassName(beanClassName);
			beanDefinition.setBeanClass(Class.forName(beanClass));
			BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition,beanClassName, null);
			//注册BeanDefinition对象
			BeanDefinitionReaderUtils.registerBeanDefinition(beanDefinitionHolder, parserContext.getRegistry());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return beanDefinition;
	}
}

       4.编写META-INF/spring.handlers文件,指定我们NamespaceHandler

http\://oss.housihai.com/schema/reyco=com.reyco.tag.core.handlers.ReycoNamespaceHandler

       5. 编写META-INF/spring.schemas文件

http\://oss.housihai.com/schema/reyco.xsd=META-INF/spring-reyco.xsd

        6. 编写配置文件  

<?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:housihai="http://oss.housihai.com/schema/reyco"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    					http://www.springframework.org/schema/beans/spring-beans.xsd
    					http://oss.housihai.com/schema/reyco
    					http://oss.housihai.com/schema/reyco.xsd">
        
 	<housihai:reyco id="testService" class="com.reyco.tag.core.service.TestService"/>
 	
</beans>

        7. 让spring可以加载写的配置文件


/**
 * @author reyco
 * @version v1.0.1
 */
@SpringBootApplication
@ImportResource(locations = { "classpath:spring.xml" })
public class TagApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(TagApplication.class, args);
	}
	
}

           8.  测试是否可以正常使用,看下图,可以正常打印test说明我们的自定义标签起作用了!

               最后可以看一下整个项目的目录结构     

至此,整个Spring自定义标签已经介绍完了...

         源码地址https://github.com/sihaihou/customTag

         Spring源码(一):深入BeanPostProcessor源码—1

         Spring源码(二):深入BeanPostProcessor源码—2

         Spring源码(三):深入Spring Bean的生命周期

         Spring源码(四):深入Spring事件监听器

         Spring源码(五):深入Spring事务

         Spring源码(六):深入自定义标签解析

         Spring源码(七):自定义标签

         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java的艺术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值