SpringMVC之Interceptor

AbstractDetectingUrlHandlerMapping类中的initApplicationContext()方法有一条线是注册处理器,另一条线是初始化拦截器。在SpringMVC之HandlerMapping中我们走读了注册处理器的过程,接下来我们看一下拦截器的初始化这条线。

配置拦截器

//在dispatcher-servlet.xml文件中添加下面代码:
//DefaultInterceptor实现HandlerInterceptor,<mvc:interceptors>配置的时候,直接MappedInterceptor。
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="interceptor.DefaultInterceptor">
        </mvc:interceptor>
</mvc:interceptors>

//WebInterceptor实现HandlerInterceptor,<bean <property>>配置的时候,判断后添加到adaptedInterceptors。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors">
        <list>
            <bean class="interceptor.DefaultInterceptor1" />
        </list>
    </property>
</bean>

备注: 上面配置文件中两种拦截器配置方式会产生两个不同的BeanNameUrlHandlerMapping实例,那个拦截器配置在前那个BeanNameUrlHandlerMapping实例执行;这样的话,后面配置的拦截器将不会被执行,所以在配置拦截器的时候选取一种方式即可。

重要接口和类

  1. HandlerExecutionChain
    Handler和Interceptor集合组成的类

  2. HandlerInterceptor
    SpringMVC拦截器基础接口

  3. AbstractHandlerMapping
    HandlerMapping的基础抽象类

  4. AsyncHandlerInterceptor

继承HandlerInterceptor的接口,额外提供了afterConcurrentHandlingStarted方法,该方法是用来处理异步请求。当Controller中有异步请求方法的时候会触发该方法。异步请求先支持preHandle、然后执行afterConcurrentHandlingStarted。异步线程完成之后执行preHandle、postHandle、afterCompletion。

  1. HandlerInterceptorAdapter
    实现AsyncHandlerInterceptor接口的抽象类

  2. WebRequestInterceptor

与HandlerInterceptor接口类似,区别是WebRequestInterceptor的preHandle没有返回值。还有WebRequestInterceptor是针对请求的,接口方法参数中没有response。

  1. MappedInterceptor

一个包括includePatterns和excludePatterns字符串集合并带有HandlerInterceptor的类。 很明显,就是对于某些地址做特殊包括和排除的拦截器。

  1. ConversionServiceExposingInterceptor

默认的<annotation-driven/>标签初始化的时候会初始化ConversionServiceExposingInterceptor这个拦截器,并被当做构造方法的参数来构造MappedInterceptor。之后会被加入到AbstractHandlerMapping的mappedInterceptors集合中。该拦截器会在每个请求之前往request中丢入ConversionService。主要用于spring:eval标签的使用。

源码走读

//AbstractDetectingUrlHandlerMapping类中initApplicationContext()实现
public void initApplicationContext() throws ApplicationContextException {
    //初始化拦截器
    super.initApplicationContext();
    detectHandlers();
}

//AbstractHandlerMapping类中initApplicationContext()实现
protected void initApplicationContext() throws BeansException {
    //<bean <property>>配置的拦截器如:DefaultInterceptor1
    extendInterceptors(this.interceptors);
    //<mvc:interceptors>配置的拦截器如:DefaultInterceptor
    detectMappedInterceptors(this.mappedInterceptors);
    //将<bean <property>>配置的拦截器添加到对应的拦截器List中
    initInterceptors();
}
AbstractHandlerMapping类中initInterceptors()实现
protected void initInterceptors() {
    if (!this.interceptors.isEmpty()) {
        for (int i = 0; i < this.interceptors.size(); i++) {
            Object interceptor = this.interceptors.get(i);
            if (interceptor == null) {
                throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
            }
            //List<MappedInterceptor>
            if (interceptor instanceof MappedInterceptor) {
                this.mappedInterceptors.add((MappedInterceptor) interceptor);
            }
            //添加到List<HandlerInterceptor>
            else {
                this.adaptedInterceptors.add(adaptInterceptor(interceptor));
            }
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,837评论 18 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,340评论 11 349
  • 姓名: 李小娜 [嵌牛导读]: SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,...
    n184阅读 3,192评论 0 4
  • 许巍在他的歌里唱道:“生活不止眼前的苟且,还有诗和远方的田野,你赤手空拳来到人世间,为找到那片海不顾一切……” 一...
    若水希言阅读 1,864评论 0 8
  • 心想事成是每一位人类心之所向的事情!那要如何才能做到心想事成,或者说:你想的正好确实是你真心想要的呢?可能有读...
    诗宝贝阅读 290评论 0 0