zoukankan      html  css  js  c++  java
  • SpringMVC之拦截器的源码浅析

        SpringMVC是目前流行的Web框架之一。今天主要是对SpringMVC中拦截器做了一个浅析。

    之前分析的DispatcherServlet类中在做doDispatcher,会有HandlerExectionChain对象,

    其中getHandler函数,获取的是一个HandlerExecutionChain对象  它包含了handlerMethod(即是Controller层对应@RequestMapping注解的函数)和interceptors集合。

    根据handlerMethod找到对应的HandlerAdapter.

       然后,调用HandlerExecutionChain的applyPreHandler方法。然后执行HandlerAdapter的核心方法handler方法,执行完后,执行PostHandler方法,

          不管是否执行成功,都会执行HandlerExecutionChain的applyAfterCompletion方法。

        拦截器有分为前置拦截和后置拦截以及完成后拦截, 后置拦截和完成后拦截的区别是方法执行后,在DispatcherServlet渲染视图之前拦截,

          而完成后拦截,是请求处理完成,并且渲染视图后进行拦截。

        以下是HandlerExecutionChain的applyPreHandle、applyPostHandle、triggerAfterCompletion方法如下:

         

       从代码中看出,即使preHandler处理失败了,triggerAfterCompletion方法也会执行。   

       

      下面我们在看一下,HandlerExecutionChain这个类的构造过程。

     这里的属性handler就是处理的方法(即是Contrller层中url路径对应带有@RequestMapping注解的函数),属性中有两个拦截器的集合,

     

          HandlerExecutionChain这个对象是从HandlerMapping这个对象中获取的。HandlerMapping是作为请求和处理之间的映射关联的角色。

    HandlerMapping的基础抽象类是AbstractHandlerMapping。

      下面是AbstractHandlerMapping类的getHandler方法。

           其中getHandlerInternal函数其实是抽象方法,由其子类实现,先找handlerMethod,然后getHandlerExecutionChain函数来构造

    HandlerExecutionChain。下面是getHandlerExecutinoChain函数。

       使用AbstractHandlerMapping对象内部的adapterInterceptors集合,判断是否匹配,当前请求的路径,若匹配则加入拦截器链中。

    不是MappedInterceptor则直接加入拦截器链中。

    拦截器的配置:

     下面是SpringMVC中拦截器的配置应用:

     1. spring-servlet.xml配置文件中添加 <mvc:interceptors>配置:

      <mvc:interceptors>

        <mvc:interceptor>

          <mvc:mapping path="/**"/>

          <mvc:exclude-mapping path="/index"/>

            <bean class="package.interceptor.xxInterceptor"/>

           </mvc:interceptor>

          </mvc:interceptors>

       2.这里配置的每个<mvc:interceptor>都会被解析成MappedInterceptor, 其中子标签<mvc:mapping path="/**"/>会被解析成MappedInterceptor的includePatterns属性,

    <mvc:exclude-mapping path="/**"/>会被解析成MappedInterceptor的excludePatterns属性;<bean/>会被解析成MappedInterceptor的interceptor属性。

    <mvc:interceptors>这个标签是被InterceptorsBeanDefinitionParser类解析。

    3.配置RequestMappingHandlerMapping,这里的interceptors集合是个Object类型的泛型集合。

       AbstractHandlerMapping抽象类只暴露了1个拦截器的set方法注入interceptors。adaptedInterceptors和mappedInterceptors均没有暴露set方法,

    因此我们只能为RequestMappingHandlerMapping配置interceptors属性。

       其实AbstractHandlerMapping内部的initInterceptors方法中,会遍历interceptors集合,然后判断各个项是否是MappedInterceptor、HandlerInterceptor、WebRequestInterceptor。  MappedInterceptor类型的拦截器会被加到mappedInterceptors集合中,HandlerInterceptor类型的会被加到adaptedInterceptors集合中,WebRequestInterceptor类型的会被适配成WebRequestHandlerInterceptorAdapter加到adaptedInterceptors集合中。 

      

      

    自定义拦截器:

    1.自定义拦截器只需要的继承HandlerIntercepterAdapter,

    然后在web.xml文件中配置如下既可以了。

    结束:

          对于SpringMVC代码怎么去实现的原理,还是充满了好奇。这个只是其中很小的一点,只要一点一点积累,

    终会对SpringMVC这种框架有个更加深入的了解.

  • 相关阅读:
    AngularJS各种'service'的区别
    js 斐波那契数列实现
    Mac下Apache+MySQL+PHP开发环境安装过程
    原生封装的js前端工具库(包含了jquery的常用功能)
    BFC 神奇背后的原理
    CSS清浮动处理(Clear与BFC)
    JavaScript实现 页面滚动图片加载(懒加载)
    CodeForce 814B
    排序算法
    uva1610
  • 原文地址:https://www.cnblogs.com/xjz1842/p/6385054.html
Copyright © 2011-2022 走看看