SpringMVC源码解析之Servlet
SpringMVC源码解析之GenericServlet和HttpServlet
SpringMVC源码解析之DispatcherServlet:生命周期init()和destroy()
SpringMVC源码解析之DispatcherServlet:请求处理
SpringMVC源码解析之RequestMappingHandlerMapping:getHandler
一、简介
getHandler是HandlerMapping接口中的唯一方法,用于根据请求找到匹配的处理器。因此getHandler也是包括RequestMappingHandlerMapping在内的所有实现类中最核心的一个方法,其方法调用链如下:
二、AbstractHandlerMapping
1. getHandler
//AbstractHandlerMapping#getHandler
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//获取handler的具体逻辑,留给子类实现
Object handler = getHandlerInternal(request);
//null handler,采用默认的handler,即属性defaultHandler
if (handler == null) {
handler = getDefaultHandler();
}
//还是null handler,直接返回null
if (handler == null) {
return null;
}
//handler是beanName, 从容器里获取对应的bean
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
//根据handler和request获取处理器链HandlerExecutionChain
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
//CORS请求的处理
if (CorsUtils.isCorsRequest(request)) {
//全局配置
CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
//handler的单独配置
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
//handler的所有配置,全局配置+单独配置
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
//根据cors配置更新HandlerExecutionChain
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
(1)调用getHandlerInternal获取匹配的处理器
(2)如果获取失败,获取默认的处理器。如果没有设置默认处理器,直接返回null。
(3)如果获取到的处理器是字符串,将其作为beanName从容器中获取对应的对象作为处理器。
(4)调用getHandlerExecutionChain封装成HandlerExecutionChain
(5)针对CORS请求做特殊处理
2. getHandlerExecutionChain
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根据url判断是否匹配
if (interceptor instanceof MappedIntercep