首先列举下几个基础知识也就是spring 文档里面的重要的一个 Special Bean Types哈。
HandlerMapping,顾名思义用于对handler的映射。主要方法
@Nullable HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
接受一个基础的request对象,返回一个HandlerExecutionChain。返回的是一个处理链哈,把拦截器和handler一起装载进去了。HandlerExecutionChain代码比较长自己看源码去。
再回到doDispatch 方法。直接上代码
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);
// Determine handler for the current request.
//决定当前request使用哪一个handler
mappedHandler = getHandler(processedRequest);
//为空就使用默认的handler.
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
//确定当前request的dandler的handler adapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
//实际调用hander方法的地方。
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) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
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()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
整个代码其实目的很明确,就是通过为request找到对应的handler 然后调用hander方法处理请求.
1,通过request对象获取handler,代码如下
// Determine handler for the current request. mappedHandler = getHandler(processedRequest);
getHandler方法为直接遍历所有的handlermapping.返回获取的第一个handler.handlermapping本身是有一个排序的哈。注意这里返回的是HandlerExecutionChain。handler和interceptor一起被打包进去了。有兴趣可以看看getHandler的实现是怎么组装interceptor。
@Nullable protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { if (this.handlerMappings != null) { for (HandlerMapping mapping : this.handlerMappings) { HandlerExecutionChain handler = mapping.getHandler(request); if (handler != null) { return handler; } } } return null; }
2.1事实上在我们获取到handler之后直接往下执行就好了。不同类型的handler直接加一个类型判断。再来个类型转换就好了。spring的做法更优雅。
持有一个handlerAdapter集合,这部分是初始化时候获取的,注册到ioc容器就行。spring通过类型加载。获取到handler后遍历handlerAdapter。通过handler的真实类型来判断是否支持处理。在handle的时候。强转handler的类型就ok。因为handlerAdapter是针对固定类型编码的。往下看选择HandlerAdapter的代码。
// Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { if (this.handlerAdapters != null) { for (HandlerAdapter adapter : this.handlerAdapters) { if (adapter.supports(handler)) { return adapter; } } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
持有一个HandlerAdapter的集合,遍历这个集合找到合适的HandlerAdapter。看一下adapter的support方法,这里就是进行判断。等于说以这种方式获取了handler的类型。因为adapter就是根据handler编写的。可以说是一对一关系。
@Override public boolean supports(Object handler) { return (handler instanceof Controller); }
adapter的handle方法很直接直接转型。adapter这部分代码使用SimpleControllerHandlerAdapter的,其它得实现大同小异哈。
@Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); }
总结
总的来说就是持有一个HandlerMapping集合。一个handlerAdapter集合,HandlerMapping遍历调用getHandler获取handler(其实是一个HandlerExecutionChain 除了handler还有其他私货拦截器),handlerAdapter集合再去通过handler遍历调用supports来判断类型。找到确定的handlerAdapter,再去执行hander方法。到这里就结束了。
引入handlerAdapter就是为了可扩展,里面就是一些类型判断和转换。