zoukankan      html  css  js  c++  java
  • spring源码剖析(三)自定义标签实现及使用

    spring源码剖析(三)自定义标签实现及使用

     

    目录(?)[+]

     
     
    首先我们来理一理如何自定义一个spring的标签,像bean标签那样使用,我们先概览一些整体的流程:
     
    1)创建一个需要扩展的组件
    2)定义一个XSD文件,描述组件内容
    3)创建一个java类,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
    4)创建一个Handler类,扩展子NameSpaceHandlerSupport,目的是将组件注册到容器。
    5)编写(添加)Spring.handlers和Spring.schemas文件。

    完成以上工作的话,那么我们就可以使用我们自定义的标签了,接下来我们来看详细的例子实现。
     

    创建pojo类

    [java] view plain copy
     
    1. package net.itaem.vo;  
    2.   
    3. public class User {  
    4.   
    5.     private String name;  
    6.     private String sex;  
    7.     private String email;  
    8.     private String id;  
    9.       
    10.     //set get method...  
    11.       
    12. }  


    定义一个xsd文件描述组件类容

    以前spring使用的是dtd文件,现在几乎使用的都是xsd文件了,xsd文件的定义如果不了解的朋友可以去http://www.phpstudy.net/e/schema/  这个网址看看,用法比较简单,这里就不介绍如何使用了,下面是按照schema的规则定义一个xsd文件
    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <schema xmlns="http://www.w3.org/2001/XMLSchema"  
    3.             targetNamespace="http://www.lexueba.com/schema/user"  
    4.             xmlns:tns="http://www.lexueba.com/schema/user"  
    5.             elementFormDefault="qualified">  
    6.   
    7.   
    8. <element name="user">  
    9.     <complexType>  
    10.         <attribute name="id" type="string" />  
    11.         <attribute name="name" type="string" />  
    12.         <attribute name="sex" type="string" />  
    13.         <attribute name="email" type="string" />  
    14.     </complexType>  
    15. </element>  
    16.   
    17. </schema>  

    实现AbstractSingleBeanDefinitionParser接口

    实现了这个接口,当spring加载文档的时候,遇到你定义的标签,他就会回调你的这个解析方法,进行你自定义的属性解析。
    [java] view plain copy
     
    1. /* 
    2.  * Copyright 2002-2013 the original author or authors. 
    3.  * 
    4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
    5.  * you may not use this file except in compliance with the License. 
    6.  * You may obtain a copy of the License at 
    7.  * 
    8.  * http://www.apache.org/licenses/LICENSE-2.0 
    9.  * 
    10.  * Unless required by applicable law or agreed to in writing, software 
    11.  * distributed under the License is distributed on an "AS IS" BASIS, 
    12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    13.  * See the License for the specific language governing permissions and 
    14.  * limitations under the License. 
    15.  */  
    16.   
    17. package net.itaem.parser;  
    18.   
    19. import net.itaem.vo.User;  
    20.   
    21. import org.springframework.beans.factory.support.BeanDefinitionBuilder;  
    22. import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;  
    23. import org.springframework.util.StringUtils;  
    24. import org.w3c.dom.Element;  
    25.   
    26.   
    27. /** 
    28.  *  
    29.  * @author Administrator 
    30.  */  
    31. public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{  
    32.   
    33.     /* (non-Javadoc) 
    34.      * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element) 
    35.      */  
    36.     @Override  
    37.     protected Class<?> getBeanClass(Element element) {  
    38.         return  User.class;  
    39.     }  
    40.       
    41.     //从elelment中解析并提取对应的元素  
    42.     @Override  
    43.     protected void doParse(Element element, BeanDefinitionBuilder builder) {  
    44.        
    45.         String name=element.getAttribute("name");  
    46.         String email=element.getAttribute("sex");  
    47.         String sex=element.getAttribute("sex");  
    48.         //将提取到的数据放入beanDefinitionBuilder 中,待完成所有的bean解析后统一放到beanfactory  
    49.         if(StringUtils.hasText(name)){  
    50.             builder.addPropertyValue("name", name);  
    51.         }  
    52.         if(StringUtils.hasText(email)){  
    53.             builder.addPropertyValue("email", email);  
    54.         }  
    55.         if(StringUtils.hasText(sex)){  
    56.             builder.addPropertyValue("sex", sex);  
    57.         }  
    58.           
    59.     }  
    60.        
    61. }  


    继承抽象类NamespaceHandlerSupport

    定义了标签,这里就是标签的处理器,处理器中会把解析类(UserBeanDefinitionParser)的实例传入spring中,使得当spring解析到该标签的时候可以回调该实例的方法。
    [java] view plain copy
     
    1. /* 
    2.  * Copyright 2002-2013 the original author or authors. 
    3.  * 
    4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
    5.  * you may not use this file except in compliance with the License. 
    6.  * You may obtain a copy of the License at 
    7.  * 
    8.  * http://www.apache.org/licenses/LICENSE-2.0 
    9.  * 
    10.  * Unless required by applicable law or agreed to in writing, software 
    11.  * distributed under the License is distributed on an "AS IS" BASIS, 
    12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    13.  * See the License for the specific language governing permissions and 
    14.  * limitations under the License. 
    15.  */  
    16.   
    17. package net.itaem.handler;  
    18.   
    19. import net.itaem.parser.UserBeanDefinitionParser;  
    20.   
    21. import org.springframework.beans.factory.xml.NamespaceHandlerSupport;  
    22.   
    23.   
    24. /** 
    25.  *  
    26.  * @author Administrator 
    27.  */  
    28. public class MyNamespaceHandler extends NamespaceHandlerSupport {  
    29.   
    30.     /* (non-Javadoc) 
    31.      * @see org.springframework.beans.factory.xml.NamespaceHandler#init() 
    32.      */  
    33.     @Override  
    34.     public void init() {  
    35.         registerBeanDefinitionParser("user", new UserBeanDefinitionParser());  
    36.     }  
    37.   
    38. }  


    修改(添加)spring.handlers文件和spring.schemas文件

    这两个文件默认路径是在META-INF这个路径下面

    修改spring.handlers 文件,添加以下内容

    http://www.lexueba.com/schema/user(自定义的)=net.itaem.handler.MyNamespaceHandler

    修改spring.schemas文件的内容,添加以下内容

    http://www.lexueba.com/schema/user.xsd(自定义的)=org/springframework/beans/factory/xml/use.xsd

    修改好之后在使用自定义标签的时候便会把这些加到xsi:schemaLocation里面去,然后spring会自己去找xsd文件以及处理器(handler)

    创建测试配置文件

    使用的时候可以加上自己定义的命名空间,然后再xsi:schemaLocation加上对应的内容,就可以使用自己定义的标签了。
    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    4.     xmlns:myname="http://www.lexueba.com/schema/user"  
    5.   
    6.     xsi:schemaLocation="  
    7.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
    8.         http://www.lexueba.com/schema/user http://www.lexueba.com/schema/user.xsd">  
    9.   
    10.      <myname:user id="beantest" name="whx" email="494863082@qq.com" sex="男"/>   
    11. </beans>  

    编写测试代码

    [java] view plain copy
     
    1. package net.itaem.test;  
    2.   
    3. import net.itaem.vo.User;  
    4.   
    5. import org.springframework.context.ApplicationContext;  
    6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
    7.   
    8. public class Test {  
    9.       
    10.     public static void main(String[] args) {  
    11.         ApplicationContext context=new ClassPathXmlApplicationContext("net/itaem/source/custom_user.xml");  
    12.         User bt=(User) context.getBean("beantest");  
    13.         System.out.println(bt);  
    14.     }  
    15.        
    16. }  

    运行结果可以看到,程序正常输出bean的信息
     

    总结

    自定义spring的标签,由于spring为我们做了大量的封装,自定义起来总体来说还是比较简单的,后续我们会看到,其实spring的aop的标签,类似这些非spring默认的标签,这些都是需要经过这些流程去实现自定义标签的。
  • 相关阅读:
    硬件——STM32 , SN74HC573锁存器
    【模拟】【杂题】jzoj 6345. 【NOIP2019模拟2019.9.8】ZYB建围墙
    归并排序求逆序对
    归并排序求逆序对
    hdu 4135
    hdu 4135
    牛客小白月赛5 A-无关(relationship)
    牛客小白月赛5 A-无关(relationship)
    HDU4027:Can you answer these queries?
    HDU4027:Can you answer these queries?
  • 原文地址:https://www.cnblogs.com/handsome1013/p/7124690.html
Copyright © 2011-2022 走看看