4.1自定义标签使用
很多情况下,我们需要为系统提供可配置化的支持,简单的做法可以直接基于Spring的标准bean来配置,但是配置较为复杂或者需要更多丰富控制的时候,会显得笨拙。此时Spring提供了可拓展的支持,拓展Spring自定义标签大致需要一下几个步骤:
- 创建一个需要拓展的组件
- 定义一个XSD文件描述组件内容
- 创建一个文件,实现BeandefinitionParse接口,用来解析XSD文件中的定义和组件定义。
- 创建一个Handler文件,拓展自NamespaceHandlerSupport,目的是将组件注册到Spring容器中。
- 编写spring.handlers和spring.schemas文件。
1)创建一个POJO,用来接收配置文件
package userDefinedXml; /** * @version 版权 Copyright(c) * @ClassName: * @Descripton: 用于Spring自定义标签解析 * @author: Shing * @date: 2020-10-21 15:45 */ public class User { private String id; private String userName; private String email; //省略get、set }
2)定义一个XSD文件描述组件内容
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.shing.com/schema/user" xmlns:tns="http://www.shing.com/schema/user" elementFormDefault="qualified"> <element name="user"> <complexType> <attribute name="id" type="string" /> <attribute name="userName" type="string" /> <attribute name="email" type="string" /> </complexType> </element> </schema>
targetnamespace、element、id、userName、email只要用于验证Spring配置文件中自定义格式。
3)创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
package userDefinedXml; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** * @version 版权 Copyright(c) * @ClassName: * @Descripton: 解析XSD文件中的定义和组件定义 * @author: Shing * @date: 2020-10-21 15:54 */ public class UserBeanDefinitionParse extends AbstractSingleBeanDefinitionParser { //Element对应的类 @Override protected Class<?> getBeanClass(Element element) { return User.class; } //从element中解析并提取对应的元素 @Override protected void doParse(Element element, BeanDefinitionBuilder builder) { String userName = element.getAttribute("userName"); String email = element.getAttribute("email"); if(StringUtils.hasText(userName)){ builder.addPropertyValue("userName",userName); } if(StringUtils.hasText(email)){ builder.addPropertyValue("email",email); } } }
4)创建一个Handler文件,拓展自NamespaceHandlerSupport,目的是将组件注册到Spring容器中。
package userDefinedXml; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; /** * @version 版权 Copyright(c) * @ClassName: * @Descripton: 将组件注册到Spring容器 * @author: Shing * @date: 2020-10-21 16:04 */ public class MyNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("user",new UserBeanDefinitionParse()); } }
以上代码很简单,无非是遇到自定义标签<user:aaa这样类似user开头的元素,将会把这个元素扔给对应的UserBeanDefinitionParser去解析。
5)编写spring.handlers和spring.schemas文件,默认在工程的/META-INF文件夹下
spring.handlers
http\://www.shing.com/schema/user=userDefinedXml.MyNamespaceHandler
spring.schemas
http\://www.shing.com/schema/user.xsd=META-INF/userDefined.xsd
到了这里,自定义配置就结束来,Spring加载到自定义标签后就会去spring.handlers,spring.schemas找对应的handler和XSD,进而找到对应的handler以及解析元素Parser,从而完成整个自定义元素的解析。spring中默认配置与自定义的区别是自定义的将解析过程交给了用户实现。
6)创建测试的配置文件,在配置文件中引入对应的命名空间以及XSD后,就可以使用自定义标签了。
customDefinition.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:myname="http://www.shing.com/schema/user" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.shing.com/schema/user http://www.shing.com/schema/user.xsd"> <myname:user id="user" userName="aaa" email="bbb" /> </beans>
package userDefinedXml; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @version 版权 Copyright(c) * @ClassName: * @Descripton: * @author: Shing * @date: 2020-10-21 16:23 */ public class customDefinitionXml { public static void main(String[] args) { ApplicationContext bf = new ClassPathXmlApplicationContext("customDefinition.xml"); User user = (User) bf.getBean("user"); System.out.println(user.getUserName()+"--"+user.getEmail()); } }


浙公网安备 33010602011771号