# springMVC **Repository Path**: losermly/spring-mvc ## Basic Information - **Project Name**: springMVC - **Description**: 基于spring6学习springMVC - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-06 - **Last Updated**: 2025-08-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 什么是MVC + M:Model(模型) + V:View(视图) + C:Controller(控制器) 优点: + 低耦合,扩展能力增强 + 代码复用性增强 + 可维护性增强 + 高内聚,让程序员更专注业务的开发 MVC架构模式 只包含了controller、model(包含了bean、service、dao层)、view ![](images/mvc架构模式.png) 三层架构模式 ![](images/三层模型.png) ## springMVC做了什么 1. 入口控制:springMVC通过DispatcherServlet作为入口控制器,负责接收请求和分发请求 2. 表单提交时可以自动将表单数据绑定到相应的javaBean对象中,只需要在控制器方法中声明对应的对象 3. IoC容器:springMVC通过IoC容器管理bean,只需要在配置对象中进行对应的配置即可 4. 统一处理请求:springMVC提供了拦截器、异常处理器等统一处理请求机制 5. 视图解析:springMVC提供了多种视图模板,如JSP、Freemarker、Velocity等,并支持国际化、主题等特性 ## springMVC的特点 ![](images/springMVC的特点.png) ![](images/note.png) ## 视图实现的核心类和接口 1. DispatcherServlet:前端控制器,核心方法(doDispatcher) 1. 负责接收前端的请求 2. 根据请求路径找到对用的处理器方法(controller.method) 3. 执行处理器方法(method) 4. 最终返回ModelAndView对象 5. 处理View 2. viewResolver接口:视图解析接口 1. ThymeleafViewResolver实现了ViewResolver接口。InternalResourceViewResolver也实现了ViewResolver接口 2. 作用:将逻辑视图名转换为物理视图名,并最终返回一个View接口 3. 核心方法:View resolveViewName(String viewName, Locale locale) throws Exception 3. View接口:视图接口 1. 作用:负责将模板语法转换为html代码,并将html响应给浏览器(渲染) 2. 核心方法:void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; 视图机制源码 ~~~java public class DispatcherServlet extends FrameworkServlet { protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 获取ModelAndView对象 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 处理视图 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception { // 解析视图进行渲染 render(mv, request, response); } protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // 将逻辑视图名转换为物理视图名 View view = resolveViewName(viewName, mv.getModelInternal(), locale, request); // 渲染视图,这个view是看程序中使用了那个模板就返回那个模板的实现类 view.render(mv.getModelInternal(), request, response); } /** * 解析视图名称 * @param viewName 视图逻辑名称 * @param model 模型 * @param locale * @param request request请求对象 * @return View 视图对象 * @throws Exception 抛出异常 */ protected View resolveViewName(String viewName, @Nullable Map model, Locale locale, HttpServletRequest request) throws Exception { /* 1. 遍历viewResolver集合,这是在配置文件中配置的, 如果配置文件中配置了多个,那么这里就会有多个viewResolver 且遍历的顺序就是配置文件中的order优先级顺序 2. 获取View 3. 返回View 4. 如果没有找到,返回null */ if (this.viewResolvers != null) { for (ViewResolver viewResolver : this.viewResolvers) { View view = viewResolver.resolveViewName(viewName, locale); if (view != null) { return view; } } } return null; } } /** * 程序中使用了Thymeleaf模板,所以这里返回的是ThymeleafViewResolver */ public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; } public class ThymeleafViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { return new ThymeleafView(viewName); } } /** * 视图接口, 负责将模板语法转换为html代码,并最终返回给浏览器进行渲染 * 程序中使用的是ThymeleafView实现类 */ public interface View { void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; } public class ThymeleafView implements View { @Override public void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { } } ~~~ ## 实现视图机制的原理描述 ![](images/实现视图机制的原理描述.png) ## 转发和重定向的区别 ![](images/转发和重定向的区别.png) ![](images/转发和重定向的区别1.png) ![](images/httpMessageConverter.png) ## springMVC执行流程 ### springMVC中DispatcherServlet的加载顺序: 1. tomcat加载Servlet的实现类(DispatcherServlet) 2. DispatcherServlet调用构造方法,构造方法调用父类FrameworkServlet的无参构造方法 ~~~java public class DispatcherServlet extends FrameworkServlet { public DispatcherServlet() { super(); } } ~~~ 3. FrameworkServlet的无参构造方法继续向上调用无参构造方法,然后类成功后,由servlet容器调用init(ServletConfig config)初始化方法 ~~~java public class FrameworkServlet extends HttpServlet { public FrameworkServlet() {} } ~~~ 4. 在GenericServlet类中有init(ServletConfig config)方法,调用父类GenericServlet的init(ServletConfig config)方法 ~~~java public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { @Override public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } /** * 抽象方法,子类实现(HttpServletBean) */ public void init() throws ServletException {} } ~~~ 5. 在HttpServletBean类中有init()方法,调用父类HttpServletBean的init()方法,init()方法中调用了initServletBean()方法 ~~~java public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware { @Override public final void init() throws ServletException { // 初始化servlet的bean initServletBean(); } /** * 初始化servlet的bean,交由子类实现(FrameworkServlet) */ protected void initServletBean() throws ServletException {} } ~~~ 6. FrameworkServlet中实现了initServletBean方法,并调用了initWebApplicationContext方法初始化web容器,在initWebApplicationContext方法中调用了onRefresh方法进行刷新web容器 ~~~java public class FrameworkServlet extends HttpServletBean { @Override protected final void initServletBean() throws ServletException { this.webApplicationContext = initWebApplicationContext(); } protected WebApplicationContext initWebApplicationContext() { onRefresh(wac); } /** * 刷新web容器,在子类中实现(DispatcherServlet) */ protected void onRefresh(ApplicationContext context) { // 在子类中实现 } } ~~~ 7. 在DispatcherServlet中实现onRefresh方法,并调用initStrategies方法初始化所有对象 ~~~java public class DispatcherServlet extends FrameworkServlet { @Override protected void onRefresh(ApplicationContext context) { initStrategies(context); } /** * 初始化所有用到的策略 */ protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } } ~~~ ![](images/DispatcherServlet依赖.png) ## springMVC中web请求流程源码分析 ```java import jakarta.servlet.ServletException; import java.nio.file.attribute.UserDefinedFileAttributeView; /** * springMVC框架的核心类 */ public class DispatcherServlet extends FrameworkServlet { /** * 初始化用到的所有对象 * @param context */ protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } /** * springMVC中web请求流程的核心方法 */ protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 将request赋值给变量processedRequest变量,防止后续对request有变动时,调整了原始的request对象 HttpServletRequest processedRequest = request; // 声明处理器执行链,包含该request对应的所有拦截器和其对应的处理器(也就是controller中的方法) // HandlerExecutionChain是SpringMVC中包含处理器和拦截器的封装类 HandlerExecutionChain mappedHandler = null; // 判断是否为文件请求 boolean multipartRequestParsed = false; // 获取当前请求的异步管理器 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { // 初始化ModelAndView对象,用来接收控制器处理结果(controller#method()) ModelAndView mv = null; // 初始化异常 Exception dispatchException = null; try { // 检查是否为文件请求,若为文件请求的话则将其request进行更改赋值给processRequest变量 processedRequest = checkMultipart(request); // 判断processedRequest和原生的request是否有变更,有的话则表示为文件请求 multipartRequestParsed = (processedRequest != request); // 获取处理器执行链 mappedHandler = getHandler(processedRequest); // 判断是否获取到处理器执行链,若没有则表示请求对应的url不存在,则返回404 if (mappedHandler == null) { // 给客户端返回404 noHandlerFound(processedRequest, response); return; } // 通过HandlerExecutionChain中的HandlerMethod获取对用的处理器适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 获取请求方法 String method = request.getMethod(); // 判断是否为get请求 boolean isGet = HttpMethod.GET.matches(method); // 判断是否为get和head请求 if (isGet || HttpMethod.HEAD.matches(method)) { // 获取最后一次修改时间 long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); // 检查是否有修改,没有修改的话直接返回,不执行后续处理 // 这是http缓存机制的实现,避免不必要的数据传输,提高性能。 // get请求若没有调整则不会重新返回,所以要使get请求每次都走服务器返回的话,就需要每次的get请求都要有变化 if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } // 预处理,执行拦截器的前置处理,拦截器返回false则不执行后续处理 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 执行处理器,返回ModelAndView对象 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 检查异步处理是否启动,如果启动的话则直接返回,不进行后续处理,异步的话不需要等待,避免重复执行 // 用于区分同步和异步的请求处理流程 if (asyncManager.isConcurrentHandlingStarted()) { return; } // 设置默认的视图名称,如果mv中没有返回视图的话,给其一个默认的视图名称 applyDefaultViewName(processedRequest, mv); // 执行拦截器的postHandler方法 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) { // 若出现异常则调用拦截器的afterCompletion方法进行处理,如记录日志异常等情况 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); } } } } /** * 处理调度结果,将controller#method()返回的结果进行处理(如渲染等) * @param request * @param response * @param mappedHandler 处理器执行链 * @param mv 处理器返回的ModelAndView对象 * @param exception * @throws Exception */ 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 mavDefiningException) { logger.debug("ModelAndViewDefiningException encountered", exception); mv = mavDefiningException.getModelAndView(); } else { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(request, response, handler, exception); errorView = (mv != null); } } // 判断mv不为空,且未被清楚,进行视图的渲染 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()) { return; } if (mappedHandler != null) { // 执行最后的拦截器处理afterCompletion mappedHandler.triggerAfterCompletion(request, response, null); } } /** * 进行视图渲染 * @param mv * @param request * @param response * @throws Exception */ protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // Determine locale for request and apply it to the response. Locale locale = (this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale()); response.setLocale(locale); View view; // 获取视图的逻辑名称 String viewName = mv.getViewName(); if (viewName != null) { // 将视图逻辑名称转换为View对象 // view实现类为ThymeleafView view = resolveViewName(viewName, mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'"); } } else { // No need to lookup: the ModelAndView object contains the actual View object. view = mv.getView(); if (view == null) { throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " + "View object in servlet with name '" + getServletName() + "'"); } } // Delegate to the View object for rendering. if (logger.isTraceEnabled()) { logger.trace("Rendering view [" + view + "] "); } try { if (mv.getStatus() != null) { request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, mv.getStatus()); response.setStatus(mv.getStatus().value()); } // 渲染视图 view.render(mv.getModelInternal(), request, response); } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("Error rendering view [" + view + "]", ex); } throw ex; } } /** * 解析视图逻辑名称为View对象 * @param viewName 视图逻辑名称 * @param model 传递给视图的model对象 * @param locale 当前请求的区域,用来对国际化进行处理的 * @param request * @return * @throws Exception */ protected View resolveViewName(String viewName, @Nullable Map model, Locale locale, HttpServletRequest request) throws Exception { // viewResolvers是配置的视图解析器,在配置文件中配置,默认是InternalResourceViewResolver(jsp)。如:FreemarkerViewResolver、ThymeleafViewResolver等 // 在程序加载时就会自动创建好 if (this.viewResolvers != null) { for (ViewResolver viewResolver : this.viewResolvers) { // viewResolver为ThymeleafViewResolver实现类,在实现类中进行具体的处理 View view = viewResolver.resolveViewName(viewName, locale); if (view != null) { return view; } } } return null; } /** * 检查是否设置视图,没有的话设置一个默认视图 * @param request * @param mv * @throws Exception */ private void applyDefaultViewName(HttpServletRequest request, @Nullable ModelAndView mv) throws Exception { if (mv != null && !mv.hasView()) { String defaultViewName = getDefaultViewName(request); if (defaultViewName != null) { mv.setViewName(defaultViewName); } } } /** * 获取处理器适配器 * @param handler 处理器执行链中的处理器方法对象(HandlerExecutionChain.HandlerMethod) * @return * @throws ServletException */ protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { // handlerAdapters也是在程序启动时就初始化好了,存放了所有的处理器适配器 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"); } /** * 获取处理器执行链 * @param request processedRequest,使用临时变量接收的浏览器发送的原生request * @return HandlerExecutionChain 返回处理器执行链 * @throws Exception */ protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { // handlerMappings在tomcat启动时就会自动初始化,存放了所有的处理器映射关系 // 其中比较重要的有RequestMappingHandlerMapping,这个主要是用来处理@RequestMapping注解的请求,用来匹配请求获取对应的执行链 if (this.handlerMappings != null) { for (HandlerMapping mapping : this.handlerMappings) { HandlerExecutionChain handler = mapping.getHandler(request); if (handler != null) { return handler; } } } return null; } } public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping implements InitializingBean { /** * 在程序启动时执行映射关系的注册 * * @param mapping * @param handler 处理器对象(controller.class) * @param method 处理器对应的执行方法(controller#method()) * */ public void registerMapping(T mapping, Object handler, Method method) { if (logger.isTraceEnabled()) { logger.trace("Register \"" + mapping + "\" to " + method.toGenericString()); } // 创建HandlerMethod对象和对应的HandlerMapping进行映射起来 this.mappingRegistry.register(mapping, handler, method); } } public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping { } /** * 具体的实现类,继承了{@link RequestMappingInfoHandlerMapping} 和{@link AbstractHandlerMethodMapping} */ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping implements MatchableHandlerMapping, EmbeddedValueResolverAware { } /** * 处理器执行链 */ public class HandlerExecutionChain { private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class); /** * HandlerMethod对象,其中包含了controller类信息和controller#method()信息 */ private final Object handler; /** * request请求方法对应的拦截器链,包含了所有这个请求的拦截器 */ private final List interceptorList = new ArrayList<>(); /** * 记录拦截器List的使用位置,方便执行完preHandler后执行postHandler和afterCompletion */ private int interceptorIndex = -1; /** * 执行前置拦截器方法,如果 */ boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { // 循环执行每一个前置拦截器方法 for (int i = 0; i < this.interceptorList.size(); i++) { HandlerInterceptor interceptor = this.interceptorList.get(i); // 若拦截器返回false,执行不通过,就根据interceptorIndex进行逆序执行afterCompletion方法 if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } return true; } /** * 通过逆序执行拦截器的afterCompletion方法 */ void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { // interceptorIndex是执行preHandler方法时执行到了那个拦截器,其他开始逆序执行 for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = this.interceptorList.get(i); try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } } /** * 处理器适配器接口 */ public interface HandlerAdapter { /** * 给定指定的处理器方法对象,判断该处理器适配器是否支持该处理器方法对象 * @param handler {@link HandlerMethod}对象,封装了controller类信息和controller#method()信息 * @return */ boolean supports(Object handler); /** * 执行处理器方法,返回ModelAndView对象,具体实现结果在对应的实现类中 * @param request processedRequest,使用临时变量接收的浏览器发送的原生request * @param response 原生的response,用于来给客户端返回消息 * @param handler {@link HandlerMethod} 处理器方法对象 * @return * @throws Exception */ ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; } /** * 实现了HandlerAdapter接口 */ public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered { /** * 执行处理器方法,返回ModelAndView对象,在方法中调用了handleInternal方法 * @param request processedRequest,使用临时变量接收的浏览器发送的原生request * @param response 原生的response,用于来给客户端返回消息 * @param handler {@link HandlerMethod} 处理器方法对象 * @return * @throws Exception */ public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); } /** * 抽象方法,具体实现逻辑由实现类中实现 * @param request * @param response * @param handlerMethod * @return * @throws Exception */ protected abstract ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception; } /** * 实现了{@link AbstractHandlerMethodAdapter}抽象类,重写handleInternal方法,实现处理器方法执行逻辑 */ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean { protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { // 初始化返回结果 ModelAndView mav; // 检查request请求方法是否支持(如GET、POST请求),不支持返回HttpRequestMethodNotSupportedException异常 // 检查是否要求有session,如果要求但不存在则抛出HttpSessionRequiredException异常 checkRequest(request); // 检查是否启用会话的同步机制, if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { // 有会话,获取同步锁对象,对其加锁进行锁定 Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // 没有会话对象,表示是第一次,不用加锁,直接执行处理器方法 mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // 未对会话进行同步处理,直接调用invokeHandlerMethod方法,获取模型和视图对象 mav = invokeHandlerMethod(request, response, handlerMethod); } // 缓存处理 if (!response.containsHeader(HEADER_CACHE_CONTROL)) { if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } } return mav; } /** * 执行处理器方法,获取返回的模型和视图对象 * @param request * @param response * @param handlerMethod * @return * @throws Exception */ protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { // 创建servletWebRequest对象,封装http请求和响应 ServletWebRequest webRequest = new ServletWebRequest(request, response); // 获取数据绑定工厂对象,用于参数的绑定 WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod); // 获取模型工厂,用于处理模型数据 ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory); // 创建可调用的处理器方法对象,对原始的处理器方法进行封装,包含了执行控制器方法所需的所有信息和功能 ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); if (this.argumentResolvers != null) { // 设置方法参数解析器,用于处理方法参数 invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); } if (this.returnValueHandlers != null) { // 设置方法返回值处理器,用于处理方法返回值 invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); } // 设置数据绑定工厂对象,用于数据的绑定 invocableMethod.setDataBinderFactory(binderFactory); // 设置参数名称解析器,用于获取参数名称 invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); // 设置方法校验器,用于对参数和返回值进行校验 invocableMethod.setMethodValidator(this.methodValidator); ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); modelFactory.initModel(webRequest, mavContainer, invocableMethod); mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect); AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); asyncWebRequest.setTimeout(this.asyncRequestTimeout); WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); asyncManager.setTaskExecutor(this.taskExecutor); asyncManager.setAsyncWebRequest(asyncWebRequest); asyncManager.registerCallableInterceptors(this.callableInterceptors); asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors); if (asyncManager.hasConcurrentResult()) { Object result = asyncManager.getConcurrentResult(); Object[] resultContext = asyncManager.getConcurrentResultContext(); Assert.state(resultContext != null && resultContext.length > 0, "Missing result context"); mavContainer = (ModelAndViewContainer) resultContext[0]; asyncManager.clearConcurrentResult(); LogFormatUtils.traceDebug(logger, traceOn -> { String formatted = LogFormatUtils.formatValue(result, !traceOn); return "Resume with async result [" + formatted + "]"; }); invocableMethod = invocableMethod.wrapConcurrentResult(result); } // 调用处理器方法(controller#method),获取模型和视图对象,核心方法 invocableMethod.invokeAndHandle(webRequest, mavContainer); if (asyncManager.isConcurrentHandlingStarted()) { return null; } return getModelAndView(mavContainer, modelFactory, webRequest); } } /** * 处理器方法对象 * 封装了处理器类和独赢的处理器方法 */ public class HandlerMethod extends AnnotatedMethod { /** * 对应的处理器类: * domainController */ private final Object bean; private final BeanFactory beanFactory; /** * bean的类型: * class org.example.controller.DomainController */ private final Class beanType; /** * 解析来源的处理器方法 * org.example.controller.DomainController#testRequest(ModelMap) */ private HandlerMethod resolvedFromHandlerMethod; /** * 方法的描述信息: * org.example.controller.DomainController#testRequest(ModelMap) */ private final String description; } /** * 视图解析接口,用来获取视图对象 */ public interface ViewResolver { /** * 解析逻辑视图名称,获取视图对象 * @param viewName 逻辑视图名称 * @param locale 当前区域(zh_CN) * @return * @throws Exception */ View resolveViewName(String viewName, Locale locale) throws Exception; } /** * 继承WebApplicationObjectSupport用来放入容器管理中 */ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSupport implements ViewResolver { } /** * ViewResolver的实现类,通过实现Ordered实现优先级 */ public class ThymeleafViewResolver extends AbstractCachingViewResolver implements Ordered { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { // ...... return new ThymeleafView(); } } /** * 视图接口,其中有渲染视图的方法 */ public interface View { /** * 渲染视图 * @param model * @param request * @param response * @throws Exception */ void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; } public abstract class AbstractThymeleafView extends WebApplicationObjectSupport implements View, BeanNameAware { } public class ThymeleafView extends AbstractThymeleafView { public void render(final Map model, final HttpServletRequest request, final HttpServletResponse response) throws Exception { .... } } ``` ## springMVC中servlet的结构 servlet规范 ```java import jakarta.servlet.ServletException; /** * servlet规范 * jakarta.servlet.GenericServlet */ public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { /** * 初始化方法 * @param config * @throws ServletException */ public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } /** * 由其实现类覆盖,实现具体逻辑 * 交由springMVC实现类来处理逻辑 {@link HttpServletBean} * @throws ServletException */ public void init() throws ServletException { } } /** * servlet规范 * jakarta.servlet.http.HttpServlet */ public abstract class HttpServlet extends GenericServlet { @Override public void init(ServletConfig config) throws ServletException { super.init(config); legacyHeadHandling = Boolean.parseBoolean(config.getInitParameter(LEGACY_DO_HEAD)); } } /** * springMVC中的实现类 * org.springframework.web.servlet.HttpServletBean */ public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware { @Override public final void init() throws ServletException { // 初始化用到的servletBean initServletBean(); } /** * 交由子类实现 {@link org.springframework.web.servlet.FrameworkServlet} * @throws ServletException */ protected void initServletBean() throws ServletException { } } /** * springMVC中的实现类 * org.springframework.web.servlet.FrameworkServlet */ public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware { /** * 初始化servletBean */ @Override protected final void initServletBean() throws ServletException { try { // 初始化webApplicationContext this.webApplicationContext = initWebApplicationContext(); // 可以通过子类实现这个方法来执行servlet的自定义初始化逻辑 initFrameworkServlet(); } catch (ServletException | RuntimeException ex) { logger.error("Context initialization failed", ex); throw ex; } } /** * 初始化webApplicationContext,初始化web的容器 * @return */ protected WebApplicationContext initWebApplicationContext() { WebApplicationContext wac = null; if (!this.refreshEventReceived) { synchronized (this.onRefreshMonitor) { // 刷新webApplicationContext中的数据 // 将handlerMapping等的数据初始化 onRefresh(wac); } } return wac; } /** * 让其子类来实现具体逻辑 * {@link DispatcherServlet} 中实现逻辑 * @param context */ protected void onRefresh(ApplicationContext context) { // For subclasses: do nothing by default. } /** * 让子类来实现具体逻辑,可以在servlet初始化时实现自定义逻辑 * @throws ServletException */ protected void initFrameworkServlet() throws ServletException { } } /** * springMVC中的核心类,web的具体处理逻辑都在这里面 * org.springframework.web.servlet.DispatcherServlet */ public class DispatcherServlet extends FrameworkServlet { protected void onRefresh(ApplicationContext context) { initStrategies(context); } /** * 核心方法,处理请求 * @param request * @param response * @throws Exception */ protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 具体的springMVC的处理逻辑 } /** * 初始化各个策略 * @param context */ protected void initStrategies(ApplicationContext context) { // 初始化文件解析 initMultipartResolver(context); // 初始化国际化解析器 initLocaleResolver(context); // 初始化主题解析 initThemeResolver(context); // 初始化处理器映射关系 initHandlerMappings(context); // 初始化处理器适配器 initHandlerAdapters(context); // 初始化处理器异常解析器 initHandlerExceptionResolvers(context); // 初始化请求转换为视图逻辑名的转换 initRequestToViewNameTranslator(context); // 初始化视图解析器 initViewResolvers(context); initFlashMapManager(context); } } ```