Spring 自定义标签的使用

迈不过友情╰ 2021-09-24 19:32 511阅读 0赞

工程目录:https://gitee.com/wuhan1/spring-parent/tree/master/spring-12
自定义标签有什么用?
自定义标签可以说是spring为了给类似你我这样的开发人员扩展组件使用的,因为它提供了一个标准的公共可插拔的接口;目前我们都知道spring非常强大,不过实际上除了spring-core和spring-beans外,其他都是通过自定义标签扩展实现的,其次还有一些开源组件也是,如dubbo等。所以,对于想扩展spring组件的小伙伴来说,了解如何自定义标签和相应的原理是必须走的第一步。

如何自定义标签?
1、编写.schemas文件,通知spring容器我们定义的xsd文件在哪里;
2、编写.xsd文件,定义配置时可以使用的属性限制或者说支持的那些属性配置;
3、编写.handlers 文件,扩展NamespaceHandler命名空间注册器和定义及解析器;
4、在xml文件中使用自定义标签

详细例子说明,工程目录
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RoajE5OTE4MQ_size_16_color_FFFFFF_t_70
1.定义bean属性,然后在xsd文件中声明

  1. package com.xqc.redis;
  2. public class RedisTag {
  3. private String id;
  4. private String ip;
  5. private Integer port;
  6. private String desc;
  7. public RedisTag(String ip, Integer port, String desc) {
  8. this.ip = ip;
  9. this.port = port;
  10. this.desc = desc;
  11. }
  12. public RedisTag() {
  13. }
  14. public String getIp() {
  15. return ip;
  16. }
  17. public void setIp(String ip) {
  18. this.ip = ip;
  19. }
  20. public Integer getPort() {
  21. return port;
  22. }
  23. public void setPort(Integer port) {
  24. this.port = port;
  25. }
  26. public String getDesc() {
  27. return desc;
  28. }
  29. public void setDesc(String desc) {
  30. this.desc = desc;
  31. }
  32. public RedisTag(String ip, Integer port) {
  33. this.ip = ip;
  34. this.port = port;
  35. }
  36. public String getId() {
  37. return id;
  38. }
  39. public void setId(String id) {
  40. this.id = id;
  41. }
  42. }

xsd文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  3. targetNamespace="http://www.example.org/schema/xqc"
  4. xmlns="http://www.example.org/schema/xqc"
  5. elementFormDefault="qualified">
  6. <xsd:element name="redis">
  7. <xsd:complexType>
  8. <xsd:attribute name="id" type="xsd:string" />
  9. <xsd:attribute name="ip" type="xsd:string" />
  10. <xsd:attribute name="port" type="xsd:string" />
  11. <xsd:attribute name="desc" type="xsd:string" />
  12. </xsd:complexType>
  13. </xsd:element>
  14. </xsd:schema>

2.通过spring.shemas指定xsd文件

  1. http\://www.example.org/schema/xqc.xsd=META-INF/xqc.xsd

类似与key=value的形式,如果找不到会去网络上下载。

3.通过spring.handlers指定自定义标签的解析器入口

  1. http\://www.example.org/schema/xqc=com.xqc.namespace.RedisNamespaceHandler

需要实现NamespaceHandler接口,我们继承的它的实现类NamespaceHandlerSupport

  1. import com.xqc.parse.RedisBeanDefinitionParser;
  2. import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
  3. public class RedisNamespaceHandler extends NamespaceHandlerSupport {
  4. public void init() {
  5. this.registerBeanDefinitionParser("redis",new RedisBeanDefinitionParser());
  6. }
  7. }

在init方法里使用我们自定义的解析器,

4.自定义的解析器需要集成BeanDefinitionParser接口,本例中集成的是它的子接口AbstractSingleBeanDefinitionParser

  1. package com.xqc.parse;
  2. import com.xqc.redis.RedisTag;
  3. import org.springframework.beans.factory.support.BeanDefinitionBuilder;
  4. import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
  5. import org.springframework.beans.factory.xml.ParserContext;
  6. import org.w3c.dom.Element;
  7. public class RedisBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
  8. @Override
  9. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  10. String ip = element.getAttribute("ip");
  11. String port = element.getAttribute("port");
  12. String desc = element.getAttribute("desc");
  13. builder.addPropertyValue("ip",ip);
  14. builder.addPropertyValue("port",Integer.parseInt(port));
  15. builder.addPropertyValue("desc",desc);
  16. }
  17. @Override
  18. protected Class<?> getBeanClass(Element element) {
  19. return RedisTag.class;
  20. }
  21. }
  22. v

按照上面的步骤,一个简单的自定义解析器就完成了,我们可以把工程打成jar包,然后在其他工程里配置使用,本例中我们就在自己当前的工程中解析使用
在applicationContext.xml中声明

  1. <!--suppress SpringFacetInspection -->
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:context="http://www.springframework.org/schema/context"
  7. xmlns:xqc="http://www.example.org/schema/xqc"
  8. xmlns:jee="http://www.springframework.org/schema/jee"
  9. xsi:schemaLocation="
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
  11. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  12. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
  13. http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
  14. http://www.example.org/schema/xqc http://www.example.org/schema/xqc.xsd">
  15. <xqc:redis id="redis" ip="localhost" port="6379" desc="redis配置"></xqc:redis>
  16. </beans>

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RoajE5OTE4MQ_size_16_color_FFFFFF_t_70 1

通过容器获取配置
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RoajE5OTE4MQ_size_16_color_FFFFFF_t_70 2

20201012230003403.png

遇到的问题总结,按照我们上面的格式如果在bean和xsd中没有声明ID,这样使用
20201012230503193.png
报错
20201012230256612.png
翻译报错信息:20201012230325120.png

发表评论

表情:
评论列表 (有 0 条评论,511人围观)

还没有评论,来说两句吧...

相关阅读