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这种框架有个更加深入的了解.
来源:https://www.cnblogs.com/xjz1842/p/6385054.html