基于Spring开发之自定义标签及其解析

网友投稿 310 2023-05-20


基于Spring开发之自定义标签及其解析

Spring框架是现在java最流行的开源框架之一,并且Spring下的各种子项目对某些特定问题的解决有很好的支持。因此,如果能在Spring 基础上实现搭建自己的一套框架(基于XML配置)。就必然需要实现一些自定义的标签,主要是方便使用我们框架的人能够快速、简单进行配置。

1. XML Schema

要想自定义标签,首先第一步需要写自己的XML Schema。XML Schema的个人感觉比较复杂,网上的教程比较简单,因此可以参照spring-beans.xsd依葫芦画瓢。这里就按照我自己的理解进行简单介绍一下吧。

1.1 最简单的标签

一个最简单的标签,形式如:

该标签只包含了若干属性,我们就在xsd文件中这么定义

标签中的tyhttp://pe是用来定义该属性的格式,例如

xsd:string 表示是一个字符串,对格式没什么要求

xsd:id 表示该属性的值是一个id,有格式要求(例如不能以数字开头)。

xsd:IDREF 表示该属性的值与某xsd:id属性的值对应

其他还有很多,例如number,double,datetime等等。

1.2 复杂点的标签

所谓复杂,其实就是嵌套的标签,形式如:

其实只要参照Spring 中标签的xsd依葫芦画瓢,首先是定义stop标签

其中,

定义了该标签的id属性,注意这里引用的是spring-beans中的type,

中定义了标签允许的子标签

定义了标签允许的属性

2. 配置文件

完成了xsd文件编写后,还需要让该文rpRzyHKdd件生效,就需要在项目的resource/META-INF包里面配置2个文件spring.handlers和spring.schemas

2.1 spring.schemas

改配置文件主要是用一个url来映射我们第一步配置好的文件,形式如下

http\://lizo.com/schema/bf.xsd=META-INF/bf.xsd

这样,就可以在Spring的xml配置文件中加入spring.schemas的url,省略掉其他的,在标签中增加如下信息

..

xmlns:bf="http://lizo.com/schema/bf"

xsi:schemaLocation="

...

http://lizo.com/schema/bf

http://lizo.com/schema/bf.xsd

">

完成这步以后,就可以在xml中写自己的标签了,例如自定义标签的namespace为bf,

2.2 spring.handlers

这个配置文件用来配置解析我们bf标签,然后生成一些BeanDefinition进行注册。例如

http\://lizo.com/schema/bf=com.lizo.config.BusinessFlowNamespaceHandlerSupport

其中 BusinessFlowNamespaceHandlerSupport就是我们用来解析标签

3. 自定义标签解析

在上一步中,我们配置了com.lizo.config.BusinessFlowNamespaceHandlerSupport类作为解析自定义标签的类,所以namespace为bf的标签,都会用这里注册的标签解析器来解析

public class BusinessFlowNamespaceHandlerSupport extends NamespaceHandlerSupport {

public void init() {

//注册用于解析的解析器

registerBeanDefinitionParser("stop", new BusinessFlowBeanDefinitionParser());

}

}

我们自定义的标签解析器BusinessFlowBeanDefinitionParser是要实现BeanDefinitionParser 接口的

public interface BeanDefinitionParser {

BeanDefinition parse(Element element, ParserContext parserContext);

}

一般来说,注册bean的基本流程为:

解析标签

根据解析的值生成BeanDefinition,

注册标签

解析标签就不用说,重点说说怎么生成BeanDefinition

3.1 生成BeanDefinition

一个最简单的BeanDefinition通过设置Class和属性的注入就可以完成。如下:

RootBeanDefinition nodeWrapDefinition = new RootBeanDefinition();

//该BeanDefinition对应的是什么类

nodeWrapDefinition.setBeanClass(StationRoutingWrap.class);

//name是解析标签后获得的值

nodeWrapDefinition.getPropertyValues().addPropertyValue("name", name);

RuntimeBeanReference

RuntimeBeanReference 用于在运行时去获取BeanDefinition,因为在我们创建这个BeanDefinition的时候我们只知道他的beanName,并不确定是否已经注册了,这个时候就需要用RuntimeBeanReference,例如

RuntimeBeanReference refBean = new RuntimeBeanReference(ref);

nodeWrapDefinition.getPropertyValues().addPropertyValue("station", refBean);

集合类BeanDefinition

某个BeanDefinition注入的属性为一个List,这个时候就需要用ManagedList(同理有ManagedMap,ManagedSet),

ManagedList routingConditions = new ManagedList();

....

nodeWrapDefinition.getPropertyValues().add("routing", routing);

3.2 注册bean

注册BeanDefinitionParser 接口的函数中有个参数ParserContext,有个方法为getRegistry(),因此,注冊bean的時候就很简单了

复制代码 代码如下:

parserContext.getRegistry().registerBeanDefinition("beanName",nodeWrapDefinition);

总结

通过以上三步,就可以实现自己定义标签,并且在Spring容器中注入相关的bean。让我们的框架使用起来更方便

..

xmlns:bf="http://lizo.com/schema/bf"

xsi:schemaLocation="

...

http://lizo.com/schema/bf

http://lizo.com/schema/bf.xsd

">

完成这步以后,就可以在xml中写自己的标签了,例如自定义标签的namespace为bf,

2.2 spring.handlers

这个配置文件用来配置解析我们bf标签,然后生成一些BeanDefinition进行注册。例如

http\://lizo.com/schema/bf=com.lizo.config.BusinessFlowNamespaceHandlerSupport

其中 BusinessFlowNamespaceHandlerSupport就是我们用来解析标签

3. 自定义标签解析

在上一步中,我们配置了com.lizo.config.BusinessFlowNamespaceHandlerSupport类作为解析自定义标签的类,所以namespace为bf的标签,都会用这里注册的标签解析器来解析

public class BusinessFlowNamespaceHandlerSupport extends NamespaceHandlerSupport {

public void init() {

//注册用于解析的解析器

registerBeanDefinitionParser("stop", new BusinessFlowBeanDefinitionParser());

}

}

我们自定义的标签解析器BusinessFlowBeanDefinitionParser是要实现BeanDefinitionParser 接口的

public interface BeanDefinitionParser {

BeanDefinition parse(Element element, ParserContext parserContext);

}

一般来说,注册bean的基本流程为:

解析标签

根据解析的值生成BeanDefinition,

注册标签

解析标签就不用说,重点说说怎么生成BeanDefinition

3.1 生成BeanDefinition

一个最简单的BeanDefinition通过设置Class和属性的注入就可以完成。如下:

RootBeanDefinition nodeWrapDefinition = new RootBeanDefinition();

//该BeanDefinition对应的是什么类

nodeWrapDefinition.setBeanClass(StationRoutingWrap.class);

//name是解析标签后获得的值

nodeWrapDefinition.getPropertyValues().addPropertyValue("name", name);

RuntimeBeanReference

RuntimeBeanReference 用于在运行时去获取BeanDefinition,因为在我们创建这个BeanDefinition的时候我们只知道他的beanName,并不确定是否已经注册了,这个时候就需要用RuntimeBeanReference,例如

RuntimeBeanReference refBean = new RuntimeBeanReference(ref);

nodeWrapDefinition.getPropertyValues().addPropertyValue("station", refBean);

集合类BeanDefinition

某个BeanDefinition注入的属性为一个List,这个时候就需要用ManagedList(同理有ManagedMap,ManagedSet),

ManagedList routingConditions = new ManagedList();

....

nodeWrapDefinition.getPropertyValues().add("routing", routing);

3.2 注册bean

注册BeanDefinitionParser 接口的函数中有个参数ParserContext,有个方法为getRegistry(),因此,注冊bean的時候就很简单了

复制代码 代码如下:

parserContext.getRegistry().registerBeanDefinition("beanName",nodeWrapDefinition);

总结

通过以上三步,就可以实现自己定义标签,并且在Spring容器中注入相关的bean。让我们的框架使用起来更方便


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:老生常谈java路径中的反斜杠和斜杠的区别
下一篇:Java微信公众平台开发(10) 微信自定义菜单的创建实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~