摘要:概述通过前三章的分析,我们简要分析了和,但对拦截器部分做详细的分析,拦截器的加载和初始化是三个相同的部分。
概述
通过前三章的分析,我们简要分析了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,该类是我们日常开发中使用最多的...
阅读 2062·2021-10-27 14:15
阅读 5179·2021-10-08 10:12
阅读 1522·2021-09-22 15:55
阅读 3520·2021-09-22 15:17
阅读 1204·2021-09-02 15:40
阅读 2000·2019-08-29 18:33
阅读 1356·2019-08-29 15:22
阅读 2575·2019-08-29 11:08