赞
踩
所有源码都来自springboot3.0.2,spring-webmvc-6.0.4

HttpServlet是抽象类,用于处理基于HTTP协议的请求和响应。
package jakarta.servlet.http;
public abstract class HttpServlet extends GenericServlet
HttpServletBean是Spring Framework中提供的一个抽象基类,用于简化开发自定义的Servlet类在 Spring环境中的配置和使用。
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware
FrameworkServlet是Spring MVC框架中的一个重要组件,它是 DispatcherServlet的抽象基类之一。作为一个抽象类,FrameworkServlet提供了一些基本的功能,比如Servlet生命周期管理等
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware
DispatcherServlet是Spring MVC 框架中的核心组件,实现整个请求处理的流程,接下来会做详细分析
public class DispatcherServlet extends FrameworkServlet
当HTTP请求打到服务器后,会先经过HttpServlet的service方法,然后执行到FrameworkServlet重写的service方法
// HttpServlet.class
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException(lStrings.getString("http.non_http"));
}
// FrameworkServlet重写了这个方法
service(request, response);
}
FrameworkServlet的service方法,如果是"DELETE", “HEAD”, “GET”, “OPTIONS”, “POST”, “PUT”, "TRACE"方法的请求会交给父类也就是HttpServlet的另一个(参数是HttpServletRequest,HttpServletResponse重载的)service方法,该service方法会根据请求类型,将任务再分发给doGet(),doPost()等方法,而这写方法都被FrameworkServlet重写了
// FrameworkServlet.class
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (HTTP_SERVLET_METHODS.contains(request.getMethod())) {
super.service(request, response);
}
else {
processRequest(request, response);
}
}
FrameworkServlet重写的doGet,doPost等方法都是调用了processRequest方法
// FrameworkServlet.class
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
FrameworkServlet的核心方法processRequest,作用于处理客户端请求的整个流程,包括初始化上下文、调用doService方法处理请求、记录请求处理的结果和时间、无论结果如何发布请求处理完毕事件等。其中处理请求的核心方法doService由子类DispatcherServlet重写实现
// FrameworkServlet.class
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 省略...
try {
// DispatcherServlet重写了这个方法
doService(request, response);
}
// 省略...
}
DispatcherServlet的doService方法的核心环节doDispatch方法
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 省略...
try {
doDispatch(request, response);
}
// 省略...
}
DispatcherServlet的doDispatch方法
// DispatcherServlet.class 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. mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 确定当前请求的处理器适配器 // Determine handler adapter for the current request. 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. 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 ServletException("Handler dispatch failed: " + err, err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new ServletException("Handler processing failed: " + err, 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); } } } }
HandlerMapping是处理器映射器,其作用是根据请求的URL路径,通过注解或者XML配置,寻找匹配的处理器(Handler)信息。
HandlerExecutionChain mappedHandler = null;
// 省略...
mappedHandler = getHandler(processedRequest);
在doDispatcher方法中,通过执行getHandler方法,获取到HandlerExecutionChain处理器执行链,并且准备好了针对当前请求最佳的处理器(比如自定义Controller组件中请求映射符合当前请求URL路径的某个方法),以及拦截器集合
// DispatcherServlet.class
@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;
}
HandlerExecutionChain的主要属性
// 处理器执行链
public class HandlerExecutionChain {
// 处理器
private final Object handler;
// 拦截器集合
private final List<HandlerInterceptor> interceptorList = new ArrayList<>();
// 拦截器索引
private int interceptorIndex = -1;
// 省略...
}
HandlerAdapter 是处理器适配器,其作用是根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
在doDispatcher方法中,通过执行getHandlerAdapter方法,遍历所有处理器适配器,返回支持当前处理器的HandlerAdapter处理器适配器
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接口的两个方法
public interface HandlerAdapter {
// 配置当前处理器适配器是否支持传入的处理器
boolean supports(Object handler);
// 执行处理
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
HandlerInterceptor的三个方法:
preHandle方法在处理程序执行之前被调用。它可以拦截请求,并在处理程序执行之前进行一些预处理操作。方法返回一个布尔值,如果是true,则继续执行处理程序;如果是false,则终止请求的处理。
postHandle 方法在处理程序执行之后、视图渲染之前被调用。它允许拦截并修改处理程序的结果模型和视图。您可以在此方法中添加一些公共的模型数据、修改视图或进行一些资源清理操作。
afterCompletion 方法是在整个请求处理完成后被调用,包括视图渲染完毕。此时拦截器可以进行一些资源清理工作,或者进行一些日志记录等。它接收一个 Exception 参数,用于捕获并处理请求处理过程中的异常。
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
DispatcherServlet的doServlet方法中拦截器的处理时机
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 省略... try { // 省略... try { // 省略... // 执行HandlerInterceptor的preHandle方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 执行处理程序 // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); // 执行HandlerInterceptor的postHandle方法 mappedHandler.applyPostHandle(processedRequest, response, mv); } // 省略... // 在processDispatchResult方法最后调用了mappedHandler.triggerAfterCompletion(request, response, null)执行HandlerInterceptor的afterCompletion方法 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } // 省略 }
Handler是处理器,和Java Servlet扮演的角色一致。HandlerAdapter接口的handle方法通过Handler执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至ModelAndView对象中。
ModelAndView mv = null;
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

举例当HandlerAdapter的实现类RequestMappingHandlerAdapter调用handle方法时,因为自身没有实现handle方法,所以会执行父类AbstractHandlerMethodAdapter的handle方法,这个handle的类型是HandlerMethod。
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
RequestMappingHandlerAdapter实现了handleInternal方法,走后面的处理逻辑最终处理并返回ModelAndView
@Override protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ModelAndView mav; checkRequest(request); // Execute invokeHandlerMethod in synchronized block if required. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // No HttpSession available -> no mutex necessary mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // No synchronization on session demanded at all... mav = invokeHandlerMethod(request, response, handlerMethod); } if (!response.containsHeader(HEADER_CACHE_CONTROL)) { if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } } return mav; }
handle处理程序返回的模型和视图,该模型和视图将由 DispatcherServlet 解析。视图可以是String 类型的视图名称,该名称需要由ViewResolver对象解析也可以直接指定View对象。该模型是一个 Map用于存储传输数据。
public class ModelAndView {
/** View instance or view name String. */
@Nullable
private Object view;
/** Model Map. */
@Nullable
private ModelMap model;
/** Optional HTTP status for the response. */
@Nullable
private HttpStatusCode status;
}

异常处理器解析器是用于处理全局异常的组件,它可以捕获和处理控制器抛出的异常,然后决定如何对异常进行处理,例如返回错误页面、返回 JSON 错误信息等。
HandlerExceptionResolver接口就一个resolveException方法,通过这个方法来进行异常处理。
public interface HandlerExceptionResolver {
@Nullable
ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}
在DispatcherServlet的doDispatch执行到processDispatchResult方法的时候,会在前面处理请求过程中捕获的可能出现的异常作为参数传递进去
// DispatcherServlet.class protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { try { ModelAndView mv = null; Exception dispatchException = null; try { // 省略... } 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 ServletException("Handler dispatch failed: " + err, err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } // 省略... }
如果传递的异常参数不为null,且不属于ModelAndViewDefiningException,则走processHandlerException方法的异常处理逻辑,并通过异常处理结果获得新的ModelAndView
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception { boolean errorView = false; if (exception != null) { if (exception instanceof ModelAndViewDefiningException) { logger.debug("ModelAndViewDefiningException encountered", exception); mv = ((ModelAndViewDefiningException) exception).getModelAndView(); } else { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); // 异常处理 mv = processHandlerException(request, response, handler, exception); errorView = (mv != null); } } // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isTraceEnabled()) { logger.trace("No view rendering, null ModelAndView returned."); } } if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Concurrent handling started during a forward return; } if (mappedHandler != null) { // Exception (if any) is already handled.. mappedHandler.triggerAfterCompletion(request, response, null); } }
在processHandlerException方法中将遍历HandlerExceptionResolver并执行resolveException方法进行实际异常逻辑的处理,整个方法执行完则返回一个新的ModelAndView
@Nullable protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) throws Exception { // Success and error responses may use different content types request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); // Check registered HandlerExceptionResolvers... ModelAndView exMv = null; if (this.handlerExceptionResolvers != null) { for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) { // 核心环节,遍历并执行HandlerExceptionResolver的resolveException方法 exMv = resolver.resolveException(request, response, handler, ex); if (exMv != null) { break; } } } if (exMv != null) { if (exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } // We might still need view name translation for a plain error model... if (!exMv.hasView()) { String defaultViewName = getDefaultViewName(request); if (defaultViewName != null) { exMv.setViewName(defaultViewName); } } if (logger.isTraceEnabled()) { logger.trace("Using resolved error view: " + exMv, ex); } else if (logger.isDebugEnabled()) { logger.debug("Using resolved error view: " + exMv); } WebUtils.exposeErrorRequestAttributes(request, ex, getServletName()); return exMv; } throw ex; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。