摘要:概述通过前三章的分析,我们简要分析了和,但对拦截器部分做详细的分析,拦截器的加载和初始化是三个相同的部分。
概述
通过前三章的分析,我们简要分析了SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping和RequestMappingHandlerMapping,但对拦截器部分做详细的分析,拦截器的加载和初始化是三个HandlerMapping相同的部分。本节补充下这块内容。
本系列文章是基于Spring5.0.5RELEASE。
类图类的继承关系,如下图:
我们知道Spring MVC将请求发送到Handler(Controller)处理器的功能是通过HandlerMapping组件完成的,HandlerMapping组件除了能找到Handler,还对拦截器进行了处理,具体实现是通过AbstractHandlerMapping抽象类完成的。
源码分析HandlerMapping
HandlerMapping接口只定义了一个方法getHandler,其作用是返回请求的处理链HandlerExecutionChain,该对象封装了请求的拦截器以及请求处理Handler,方法定义如下:
@Nullable HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
AbstractHandlerMapping
类声明源码如下:
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport implements HandlerMapping, Ordered { // ... ... }
从类的定义可知道,AbstractHandlerMapping抽象类继承WebApplicationObjectSupport并实现了HandlerMapping和Ordered接口,其中:
继承WebApplicationObjectSupport类提供了上下文ApplicationContext和ServletContext
实现HandlerMapping接口为我们提供查找handler处理器功能
实现Ordered接口,以提供排序能力,比如系统中使用多个HandlerMapping,可以定义每个HandlerMapping的顺序
简言之,AbstractHandlerMapping类为我们提供上下文环境、初始化拦截器并封装到HandlerExecutionChain对象中。
该类的入口方法,源代码如下:
/** * 初始化拦截器 */ @Override protected void initApplicationContext() throws BeansException { // 提供给子类去重写的,不过Spring并未去实现 extendInterceptors(this.interceptors); // 加载拦截器 detectMappedInterceptors(this.adaptedInterceptors); // 归并拦截器 initInterceptors(); } /** * 空实现 */ protected void extendInterceptors(List
至此,拦截器初始化完成,接下来我们分析getHandler方法,源码如下:
/** * 返回请求处理的HandlerExecutionChain */ @Override @Nullable public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { // getHandlerInternal()为抽象方法,具体需子类实现 Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = obtainApplicationContext().getBean(handlerName); } // 将请求处理器封装为HandlerExectionChain HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); // 对跨域的处理 if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; } /** * 钩子函数,需子类实现 */ @Nullable protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception; /** * 构建handler处理器的HandlerExecutionChain,包括拦截器 */ protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); // 迭代添加拦截器 for (HandlerInterceptor interceptor : this.adaptedInterceptors) { // 如果拦截器是MappedInterceptor,判断是否对该handler进行拦截,是的情况下添加 if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } else { // HandlerInterceptor直接添加,即通过HandingMapping属性配置的拦截器 chain.addInterceptor(interceptor); } } return chain; }总结
本节我们补充了拦截器的加载初始化过程以及getHandler方法的实现分析,希望对大家有所帮助。
最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69510.html
摘要:接口接口作用是将请求映射到处理程序,以及预处理和处理后的拦截器列表,映射是基于一些标准的,其中的细节因不同的实现而不相同。该参数是类型,作用是检查所有的映射解析器或使用或为的,默认为,即从上下文中检查所有的。 概述 在Spring MVC启动章节https://segmentfault.com/a/1190000014674239,介绍到了DispatcherServlet的onRef...
摘要:与类图对比,类继承自抽象类,其又继承自抽象类,再往上继承关系与一致。创建初始化上一章我们分析了的创建初始化过程,的创建初始化过程与一样,方法的入口在抽象类中的方法。至此,代码编写完毕。 概述 本节我们继续分析HandlerMapping另一个实现类BeanNameUrlHandlerMapping,从类的名字可知,该类会根据请求的url与spring容器中定义的bean的name属性值...
摘要:概述上一节我们分析了的初始化过程,即创建并注册,本章我们分析下的请求处理过程,即查找。本系列文章是基于。最后创建了群方便大家交流,可扫描加入,同时也可加我,共同学习共同进步,谢谢 概述 上一节我们分析了RequestMappingHandlerMapping的初始化过程,即创建并注册HandlerMehtod,本章我们分析下RequestMappingHandlerMapping的请求...
摘要:由于抽象类重写了父类的方法,所以此时会调用的方法,在该方法中通过调用父类的方法,该方法通过模板方法模式最终调到类的方法。分析该类间接实现了接口,直接实现该接口的是抽象类,映射与请求。 概述 在前一章https://segmentfault.com/a/1190000014901736的基础上继续分析,主要完成SimpleUrlHandlerMapping类的原理。 本系列文章是基于Sp...
摘要:默认支持该策略。以上是对的宏观分析,下面我们进行内部细节分析。整体流程一通过实现接口,完成拦截器相关组件的初始化调用类的方法。总结本文主要分析了的初始化过程,希望对大家有帮助。随着学习的深入,后面有时间在分析下期中涉及的关键,比如等等。 概述 本节我们继续分析HandlerMapping另一个实现类ReqeustMappingHandlerMapping,该类是我们日常开发中使用最多的...
阅读 1775·2021-10-27 14:15
阅读 3834·2021-10-08 10:12
阅读 1167·2021-09-22 15:55
阅读 3230·2021-09-22 15:17
阅读 832·2021-09-02 15:40
阅读 1748·2019-08-29 18:33
阅读 1098·2019-08-29 15:22
阅读 2355·2019-08-29 11:08