目录
一、获取处理器流程
1、获取处理器流程流程图
2、DispatcherServlet组件
2.1、doService()
2.2、doDispatch()逻辑
2.3、getHandler()逻辑
3、AbstractHandlerMapping组件
4、RequestMappingInfoHandlerMapping组件
5、AbstractHandlerMethodMapping组件
5.1、getHandlerInternal()逻辑
5.2、lookupHandlerMethod()逻辑
客户端请求过来,经过一系列的servlet,进来到DispatcherServlet控制器,经过上图的方法调用链路,经过映射器处理,交由注册机处理获取映射的处理器。当然在系统初始化的时候已经做了一些工作,才能获取处理器。
/**
* 公开特定于 DispatcherServlet 的请求属性,并为实际分派委托 # doDispatch。
*/
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 请求日志
logRequest(request);
//在包含的情况下保留请求属性的快照,以便能够在包含后恢复原始属性。
Map attributesSnapshot = null;
// WebUtils.isIncludeRequest(request)
if (true) {
attributesSnapshot = new HashMap<>();
// 获取属性名称并遍历
Enumeration> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// 使框架对象对处理程序和视图对象可用。
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
if (this.flashMapManager != null) {
// this.flashMapManager.retrieveAndUpdate(request, response);
FlashMap inputFlashMap = null;
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
}
RequestPath previousRequestPath = null;
if (this.parseRequestPath) {
previousRequestPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
ServletRequestPathUtils.parseAndCache(request);
}
try {
doDispatch(request, response);
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// 还原原始属性快照,以防包含。
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
}
}
对请求request参数设置一些属性,重点是调用doDispatch(request, response);处理
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
// 异步管理器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 确定当前请求的处理程序
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 确定当前请求的处理程序适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 如果处理程序支持,则处理上次修改的标头。
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 实际上调用处理程序
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 处理调度结果,视图解析
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// 而不是 postHandle 和 after Completion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// 清理由多部分请求使用的所有资源。
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
处理到处理程序的实际分派该处理程序将通过按顺序应用 servlet 的 HandlerMaps 来获得。HandlerAdapter 将通过查询 servlet安装的 HandlerAdapter 来获得,以找到第一个支持处理程序类的 HandlerAdapter。所有 HTTP 方法都由此方法处理。这取决于 HandlerAdapter 或者 Handler 本身来决定哪些方法是可以接受的。这个是整个DispatcherServlet的核心处理逻辑,获取处理器、适配器等处理逻辑,调用getHandler()进入下一个处理逻辑。
/**
* 为此请求返回 HandlerExectionChain。
*/
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
// 遍历DispatcherServlet的handlerMappings字段,取出处理器
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
调用HandlerMapping接口getHandler()方法,交给它的实现类AbstractHandlerMapping组件的getHandler()方法处理。
@Override
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 999520
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean名称还是已解析处理程序?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
//确保为拦截器和其他人提供缓存的 lookupPath
if (!ServletRequestPathUtils.hasCachedPath(request)) {
initLookupPath(request);
}
// 根据处理器以及请求获取处理链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
logger.debug("Mapped to " + executionChain.getHandler());
}
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = getCorsConfiguration(handler, request);
if (getCorsConfigurationSource() != null) {
CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
config = (globalConfig != null ? globalConfig.combine(config) : config);
}
if (config != null) {
config.validateAllowCredentials();
}
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
查找给定请求的处理程序,如果没有找到特定的处理程序,则返回到默认处理程序。
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
request.removeAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
try {
// 调用父类方法处理
return super.getHandlerInternal(request);
}
finally {
// 清理
ProducesRequestCondition.clearMediaTypesAttribute(request);
}
}
/**
* 查找给定请求的处理程序方法。
*/
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 初始化用于请求映射的路径。
String lookupPath = initLookupPath(request);
// 加锁
this.mappingRegistry.acquireReadLock();
try {
// 查找处理器方法
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
// 释放锁
this.mappingRegistry.releaseReadLock();
}
}
/**
* 查找当前请求的最佳匹配处理程序方法。如果找到多个匹配,则选择最佳匹配。
*/
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List matches = new ArrayList<>();
// 返回给定 URL 路径的匹配项。不是线程安全的。
List directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
if (directPathMatches != null) {
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
// 退回所有登记。
addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
}
if (!matches.isEmpty()) {
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
Comparator comparator = new MatchComparator(getMappingComparator(request));
// 排序
matches.sort(comparator);
bestMatch = matches.get(0);
if (logger.isTraceEnabled()) {
logger.trace(matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(request)) {
for (Match match : matches) {
if (match.hasCorsConfig()) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
}
}
else {
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.getHandlerMethod().getMethod();
Method m2 = secondBestMatch.getHandlerMethod().getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
}
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
// 当找到匹配的映射时调用。
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.getHandlerMethod();
}
else {
// 当没有找到匹配的映射时调用。
return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
}
}
查找当前请求的最佳匹配处理程序方法。如果找到多个匹配,则选择最佳匹配。
到此处理完毕