SpringMVC源码情操陶冶-InterceptorsBeanDefinitionParser拦截器解析器

解析mvc:interceptors节点

观察下InterceptorsBeanDefinitionParser的源码备注

/**
 * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a
 * {@code interceptors} element to register a set of {@link MappedInterceptor} definitions.
 *
 * @author Keith Donald
 * @since 3.0
 */

从官方注释可知,此解析器的作用是解析mvc:interceptors节点并注册成MappedInterceptorsDefinition集合

mvc:interceptors的配置使用

    <!-- 拦截器设置 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
              <!-- 静态资源不拦截 -->          
            <mvc:exclude-mapping path="/mobile/**"/>
            <mvc:exclude-mapping path="/pc/**"/>
            <!-- 主页不拦截 -->
            
            <!-- 特殊user资源获取不拦截 -->
            <bean class="com.du.wx.interceptor.UserInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>

InterceptorsBeanDefinitionParser#parse

直接观察公用接口方法parse(),源码奉上

    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        //CompositeComponentDefinition表示其可以装载多个ComponentDefinition
        CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
        parserContext.pushContainingComponent(compDefinition);
        
        //允许mvc:interceptors拥有path-matcher属性,表示 路径匹配解析器
        RuntimeBeanReference pathMatcherRef = null;
        if (element.hasAttribute("path-matcher")) {
            pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));
        }
        //查询mvc:interceptors节点下的bean/ref/interceptor标签
        List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");
        for (Element interceptor : interceptors) {
            //采用MappedInterceptor作为beanClass
            RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
            mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));
            mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

            ManagedList<String> includePatterns = null;
            ManagedList<String> excludePatterns = null;
            Object interceptorBean;
            //解析mvc:interceptor节点
            if ("interceptor".equals(interceptor.getLocalName())) {
                //解析mvc:mapping节点中的path属性,保存里面的拦截路径集合
                includePatterns = getIncludePatterns(interceptor, "mapping");
                //解析mvc:exclude-mapping节点中的path属性,保存里面的放行路径集合
                excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");
                //解析bean标签/ref标签,并封装成beanDefinition
                Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);
                interceptorBean = parserContext.getDelegate().parsePropertySubElement(beanElem, null);
            }
            else {
            //解析bean标签/ref标签,并封装成beanDefinition
                interceptorBean = parserContext.getDelegate().parsePropertySubElement(interceptor, null);
            }
            //MappedInterceptor类的构造函数可接受三个参数
            /**
            **public MappedInterceptor(String[] includePatterns, String[] excludePatterns, HandlerInterceptor interceptor)
            **
            */
            mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);
            mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
            mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);
            //为MappedInterceptor添加pathMatcher属性
            if (pathMatcherRef != null) {
                mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
            }
            //保存到spring的bean工厂中
            String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
            parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));
        }

        parserContext.popAndRegisterContainingComponent();
        return null;
    }

小结

  • 解析mvc:interceptors,其会封装为MappedInterceptor类,进而保存
  1. 拦截路径匹配集合includePatterns
  2. 不拦截路径匹配集合excludePatterns
  3. 拦截处理器interceptor,其必须是HandlerInterceptor的实现类
  4. 路径匹配处理器,如果mvc:interceptors设定了path-matcher属性,默认为AntPathMatcher
  • MappedInterceptor其内部包含了HandlerInterceptor集合,并添加了路径的映射属性。对匹配的路径调用相应的HandlerInterceptors

  • mvc:interceptors注册的拦截器在AbstractHandlerMapping类中通过matches()方法被调用,具体调用见Springmvc源码

转载于:https://www.cnblogs.com/question-sky/p/7077788.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值