• Spring自定义标签


    一、标签解析原理:

    1、Spring通过XML解析程序将其解析为DOM树,

    2、通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition。

    3、再通过Spring自身的功能对BeanDefinition实例化对象。

    二、自定义标签步骤

    1、定义三个文件

      META-INF/soring.handlers 指定命名空间解析实现类

      META-INF/spring.schemas  指定命名空间文件

      META-INF/xxx.xsd 定义命名空间

    2、实现NameSpace(命名空间)解析类(继承NamespaceHandlerSupport)

    3、配置相应element元素的Parser(实现BeanDefinitionParser接口)和Bean(例如实现InitializingBean, DisposableBean,ApplicationContextAware, ApplicationListener,要看配置在element需要哪些属性)

    三、应用案例

    以dubbo框架为例,可以看到:

    1、3个属性文件

    META-INF/spring.handlers

    http://www.newlandframework.com/dubbo=com.newlandframework.rpc.spring.DubboNamespaceHandler

    META-INF/spring.schemas

    http://www.newlandframework.com/dubbo/dubbo.xsd=META-INF/dubbo.xsd

    dubbo.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns="http://www.newlandframework.com/dubbo" 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                xmlns:beans="http://www.springframework.org/schema/beans" 
                targetNamespace="http://www.newlandframework.com/dubbo" 
                elementFormDefault="qualified" 
                attributeFormDefault="unqualified">
        <xsd:import namespace="http://www.springframework.org/schema/beans"/>
        <xsd:element name="service">
            <xsd:complexType>
                <xsd:complexContent>
                    <xsd:extension base="beans:identifiedType">
                        <xsd:attribute name="interfaceName" type="xsd:string" use="required"/>
                        <xsd:attribute name="ref" type="xsd:string" use="required"/>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="registry">
            <xsd:complexType>
                <xsd:complexContent>
                    <xsd:extension base="beans:identifiedType">
                        <xsd:attribute name="ipAddr" type="xsd:string" use="required"/>
                        <xsd:attribute name="protocol" type="xsd:string" use="required"/>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="reference">
            <xsd:complexType>
                <xsd:complexContent>
                    <xsd:extension base="beans:identifiedType">
                        <xsd:attribute name="interfaceName" type="xsd:string" use="required"/>
                        <xsd:attribute name="ipAddr" type="xsd:string" use="required"/>
                        <xsd:attribute name="protocol" type="xsd:string" use="required"/>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>

    2、Handler解析类

    DubboNamespaceHandler

    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.alibaba.dubbo.config.spring.schema;
    
    import com.alibaba.dubbo.common.Version;
    import com.alibaba.dubbo.config.*;
    import com.alibaba.dubbo.config.spring.AnnotationBean;
    import com.alibaba.dubbo.config.spring.ReferenceBean;
    import com.alibaba.dubbo.config.spring.ServiceBean;
    import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
    
    /**
     * DubboNamespaceHandler
     *
     * @export
     */
    public class DubboNamespaceHandler extends NamespaceHandlerSupport {
    
        static {
            Version.checkDuplicate(DubboNamespaceHandler.class);
        }
    
        public void init() {
            registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
            registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
            registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
            registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
            registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
            registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
            registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
            registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
            registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
            registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
        }
    
    }

    3、定义parser解析bean文件

    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.alibaba.dubbo.config.spring.schema;
    
    import com.alibaba.dubbo.common.Constants;
    import com.alibaba.dubbo.common.extension.ExtensionLoader;
    import com.alibaba.dubbo.common.logger.Logger;
    import com.alibaba.dubbo.common.logger.LoggerFactory;
    import com.alibaba.dubbo.common.utils.ReflectUtils;
    import com.alibaba.dubbo.common.utils.StringUtils;
    import com.alibaba.dubbo.config.*;
    import com.alibaba.dubbo.config.spring.ReferenceBean;
    import com.alibaba.dubbo.config.spring.ServiceBean;
    import com.alibaba.dubbo.rpc.Protocol;
    import org.springframework.beans.PropertyValue;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanDefinitionHolder;
    import org.springframework.beans.factory.config.RuntimeBeanReference;
    import org.springframework.beans.factory.config.TypedStringValue;
    import org.springframework.beans.factory.support.ManagedList;
    import org.springframework.beans.factory.support.ManagedMap;
    import org.springframework.beans.factory.support.RootBeanDefinition;
    import org.springframework.beans.factory.xml.BeanDefinitionParser;
    import org.springframework.beans.factory.xml.ParserContext;
    import org.w3c.dom.Element;
    import org.w3c.dom.NamedNodeMap;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.regex.Pattern;
    
    /**
     * AbstractBeanDefinitionParser
     *
     * @export
     */
    public class DubboBeanDefinitionParser implements BeanDefinitionParser {
    
        private static final Logger logger = LoggerFactory.getLogger(DubboBeanDefinitionParser.class);
        private static final Pattern GROUP_AND_VERION = Pattern.compile("^[\-.0-9_a-zA-Z]+(\:[\-.0-9_a-zA-Z]+)?$");
        private final Class<?> beanClass;
        private final boolean required;
    
        public DubboBeanDefinitionParser(Class<?> beanClass, boolean required) {
            this.beanClass = beanClass;
            this.required = required;
        }
    
        ......
    }

     

  • 相关阅读:
    ubuntu安装到选择位置时闪退
    linux下复制一个文件的内容到另一个文件
    ssh免密码登陆
    使用pymongo需要手动关闭MongoDB Connection吗?
    关于支付宝和微信使用的浏览器
    使用poi导出固定excel的模板,出现汉字不能自动设置行宽
    使用poi进行数据的导出Demo
    遍历map集合的方法
    用来遍历map集合的方法
    Idea中用来遍历list集合的快捷键
  • 原文地址:https://www.cnblogs.com/wangwanchao/p/6233097.html
Copyright © 2020-2023  润新知