SpringMVC之拦截器的源码浅析

孤人 提交于 2020-01-22 20:41:49

    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这种框架有个更加深入的了解.

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!