beanfactory篇-(十四)自定义标签是如何奏效的-九零后大叔的技术博客

沙海 2021年4月24日09:20:57Java评论39字数 5556阅读18分31秒阅读模式
摘要

回顾:通过前面一个章节的了解,我们大概清楚的了解了spring默认标签的解析过程。那么本章节和后面一个章节,我将来细致的看看自定义标签如何使用以及自定义标签是如何成功的被解析的。

文章源自JAVA秀-https://www.javaxiu.com/19912.html

回顾:通过前面一个章节的了解,我们大概清楚的了解了spring默认标签的解析过程。那么本章节和后面一个章节,我将来细致的看看自定义标签如何使用以及自定义标签是如何成功的被解析的。文章源自JAVA秀-https://www.javaxiu.com/19912.html

文章源自JAVA秀-https://www.javaxiu.com/19912.html

一、自定义标签的基础知识

1.spring的默认标签与自定义标签
[1] 常用的默认标签和使用如下:文章源自JAVA秀-https://www.javaxiu.com/19912.html

<import resource="applicationContext-dao.xml"/>

<alias name="sqlSessionFactory" alias="sqlSessionFactory1"/>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 配置数据源 -->
    <property name="dataSource" ref="dataSourceMaster"/>
    <!-- 加载mybatis的配置文件 -->
    <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"/>
    <!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
    <property name="mapperLocations" value="classpath*:com/minesoft/tutorial/mapper/**/*.xml" />
</bean>

[2] 常用的自定义标签和使用如下:文章源自JAVA秀-https://www.javaxiu.com/19912.html

<!-- 配置注解扫描 -->
<context:component-scan base-package="com.minesoft.tutorial,com.minesoft.tutorial.controller">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!-- 属性文件配置 -->
<context:property-placeholder location="classpath*:properties/*.properties" ignore-unresolvable="true" order="2"/>

<!-- 事物处理 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager" order="2"/>

<!-- 配置切面处理 -->
<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>

<!--配置静态资源访问路径-->
<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>

2.自定义标签的相关概念文章源自JAVA秀-https://www.javaxiu.com/19912.html

[1] 标签命名空间和标签格式校验文件介绍。首先我们先看看applicationContext.xml文件头信息:文章源自JAVA秀-https://www.javaxiu.com/19912.html

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc" 
   xmlns:aop="http://www.springframework.org/schema/aop"

   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

每一个自定义标签都归属到一个命名空间名下,而applicationContext.xml文件的头部的这些信息就是该文件内部所有使用自定标签所对应的命名空间。很类似于我们在使用某个java类的时候,我们需要在文件的头部import这个我们需要使用的java类的全限定名;同样的道理,我们想要使用某个自定义标签的时候,我们也需要在文件的头部引入这个自定义标签的命名空间。文章源自JAVA秀-https://www.javaxiu.com/19912.html

不同于java的地方在于,除了引入这个命名空间之外,我们还需要多一步操作,就是指定一个自定义标签格式校验文件,也就是xsd文件。也就是在xsi:schemaLocation=后面添加自己所使用的自定义标签的格式校验文件。上述的例子中,我们看到了有spring-beans.xsd、spring-context.xsd、spring-mvc.xsd、spring-aop.xsd等等的标签格式校验文件,spring-context.xsd用于校验context标签,spring-mvc.xsd用于校验mvc标签,spring-aop.xsd用于校验aop标签。如果我们想要创建一个属于我们自己的自定义标签,那么我们也一定要创建一个xsd文件。文章源自JAVA秀-https://www.javaxiu.com/19912.html

[2] spring.handlers和spring.schemas文件
我们在翻看其它的jar包的时候,经常发现别人的jar包里面经常会有两个文件,那么这两个文件是做什么的呢?二者都可以理解为一个Map信息文件,里面存储的信息都是键值对。所不同的是:
spring.handlers文件的键值对是哪个自定义标签由哪个业务类进行解析。
spring.schemas文件的键值对是哪个自定义标签由哪个路径下的xsd文件校验该标签是否合法。文章源自JAVA秀-https://www.javaxiu.com/19912.html

[3] 到此为止我们知道,我们要创建一个属于自己的自定义标签,有三步必不可少(无先后顺序关系)。
第一步:我们要创建一个自定义标签合法性校验文件
第二步:我们要创建一个自定义标签与该标签解析类的绑定关系文件
第三步:我们要创建一个自定义标签解析类文件文章源自JAVA秀-https://www.javaxiu.com/19912.html

二、如何创建一个自定义标签并使用

1.创建一个jar包工程如下(不含任何文件):文章源自JAVA秀-https://www.javaxiu.com/19912.html

beanfactory篇-(十四)自定义标签是如何奏效的-九零后大叔的技术博客 文章源自JAVA秀-https://www.javaxiu.com/19912.html

2.创建需要扩展的组件,创建一个Custom类文件。文章源自JAVA秀-https://www.javaxiu.com/19912.html

@Data
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class Custom {

    private Long id;
    private String name;
    private String mobile;
    private String bankcard;
    private String identity;

}

3.在resources文件夹的META-INF目录下,定义XSD文件描述组件内容文章源自JAVA秀-https://www.javaxiu.com/19912.html

<xsd:schema xmlns="http://www.minesoft.com/schema/minesoft"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"
            targetNamespace="http://www.minesoft.com/schema/minesoft">

    <xsd:element name="minesoft">
        <xsd:complexType>
            <xsd:attribute name="id" type="xsd:long"/>
            <xsd:attribute name="name" type="xsd:string"/>
            <xsd:attribute name="mobile" type="xsd:string"/>
            <xsd:attribute name="bankcard" type="xsd:string"/>
            <xsd:attribute name="identity" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

4.创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义文章源自JAVA秀-https://www.javaxiu.com/19912.html

public class MinesoftBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

    @Override
    protected Class<?> getBeanClass(Element element) {
        return Custom.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {

        Long id = Long.valueOf(element.getAttribute("id"));
        String name = element.getAttribute("name");
        String mobile = element.getAttribute("mobile");
        String bankcard = element.getAttribute("bankcard");
        String identity = element.getAttribute("identity");

        if (id != null) {
            builder.addPropertyValue("id", id);
        }

        if (StringUtils.hasText(name)) {
            builder.addPropertyValue("name", name);
        }

        if (StringUtils.hasText(mobile)) {
            builder.addPropertyValue("mobile", mobile);
        }

        if (StringUtils.hasText(bankcard)) {
            builder.addPropertyValue("bankcard", bankcard);
        }

        if (StringUtils.hasText(identity)) {
            builder.addPropertyValue("identity", identity);
        }
    }
}

5.创建Handler文件,扩展至NamespaceHandlerSupport,目的是将组件注册到Spring容器文章源自JAVA秀-https://www.javaxiu.com/19912.html

public class MinesoftNamespaceHandler extends NamespaceHandlerSupport {

    public void init() {
        registerBeanDefinitionParser("minesoft", new MinesoftBeanDefinitionParser());
    }
}

6.编写spring.handlers和spring.schemas文件
spring.handlers文件内容如下文章源自JAVA秀-https://www.javaxiu.com/19912.html

http\://www.minesoft.com/schema/minesoft=com.minesoft.custom.schema.MinesoftNamespaceHandler

spring.schemas文件内容如下文章源自JAVA秀-https://www.javaxiu.com/19912.html

http\://www.minesoft.com/schema/minesoft/minesoft.xsd=/META-INF/minesoft.xsd

将上面的六个步骤弄完之后,我们在命令行或者在idea左侧工具栏使用install功能,将当前的工程打成jar包部署到本地仓库。文章源自JAVA秀-https://www.javaxiu.com/19912.html

7.开始测试文章源自JAVA秀-https://www.javaxiu.com/19912.html

首先我们新创建一个测试工程,并在该测试工程的applicationContext.xml文件中添加下面的自定义标签(另外记得在新测试工程pom文件里面依赖前面打的jar包)。文章源自JAVA秀-https://www.javaxiu.com/19912.html

<minesoft:minesoft id="1000" name="sam" mobile="16878765436" identity="4305229387366524X" bankcard="7265382763772"/>

其次我们在测试工程的单元测试类执行如下代码:文章源自JAVA秀-https://www.javaxiu.com/19912.html

ClassPathXmlApplicationContext cac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Custom custom = cac.getBean(Custom.class);
System.out.println(JSONObject.toJSONString(custom));
cac.close();

执行上面的代码,我们会发现,我们在applicationContext.xml中使用的自定义标签被spring成功的解析生效了。该标签被解析成了一个Custom业务bean对象,该自定义标签的使用和bean默认标签的使用非常类似。文章源自JAVA秀-https://www.javaxiu.com/19912.html

beanfactory篇-(十四)自定义标签是如何奏效的-九零后大叔的技术博客 文章源自JAVA秀-https://www.javaxiu.com/19912.html

更多知识请关注公众号文章源自JAVA秀-https://www.javaxiu.com/19912.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定