// Determine handler for the current request. mappedHandler = getHandler(processedRequest); // 找到与之对应的 Handler if (mappedHandler == null) { noHandlerFound(processedRequest, response); // 未找到 Handler 返回 404 return; }
// Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 对 handler 进行适配
// Process last-modified header, if supported by the handler. 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; }
if (asyncManager.isConcurrentHandlingStarted()) { return; }
applyDefaultViewName(processedRequest, mv); // mv 不为null,则对页面进行渲染 mappedHandler.applyPostHandle(processedRequest, response, mv); // postHandler 拦截器 } 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); } // 处理收尾工作,调用拦截器的 afterCompletion 方法 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); } } } }
Web服务如何与Spring容器接轨
容器 onRefresh 方法
AbstractApplicationContext#onRefresh 方法给子类提供了一个扩展点,用于去初始化其他 Bean。web服务本质是一个 Spring 容器,所以会去继承 AbstractApplicationContext,并重写 onRefresh 方法,之后在该方法中来启动 web 服务。
启动 web Server
AnnotationConfigServletWebServerApplicationContext 是基于注解实现的 Servlet web 容器
之后我们一起去探究 Servlet Web 服务是如何进行启动的,首先来看到 AnnotationConfigServletWebServerApplicationContext@onRefresh() 方法,在该方法中会去调用 createWebServer() 来创建 Web 服务,我们这里只需关注该方法即可。
首先会去获取本地的 webServer,如果当前 Web 服务并未初始化,那么通过 ServletWebServerFactory 方法传递 ServletContextInitializer 来创建一个 web 服务。之后向 Spring 容器中注入 WebServerGracefulShutdownLifecycle(web容器销毁时收尾工作)、WebServerStartStopLifecycle (用于启动web Server),这两个 Bean 都是依赖 spring 生命周期来进行实现。
Web Server 创建细节我们不进行探究,主要是对 Web Server 启动来进行讲解,在 WebServerStartStopLifecycle 中,该对象实现了 SmartLifecycle 接口,该接口会在spring 容器启动之后进行回调,在这回调期间会将 Web Server 进行启动。Web Server 启动后通过一个标志位(running)标识该 Web Server 已经启动,然后广播一个 ServletWebServerInitializedEvent 事件用于在其它地方做一些额外工作。