好看的皮囊千篇一律、有趣的灵魂万里挑一
文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。还有机会获得内推名额。
文章目录
- Spring MVC 源码解析
- 1. DispatcherServlet
- 2. HandlerMapping
- 3. HandlerAdapter
- 4. ViewResolver
- 5. ModelAndView
- 总结
Spring MVC 源码解析
Spring MVC 是 Spring 框架的核心组件之一,用于构建基于 Web 的应用程序。它实现了 Model-View-Controller(MVC)模式,使开发者可以方便地管理业务逻辑、视图和数据交互。以下是 Spring MVC 请求处理的主要流程及源码解析。
1. DispatcherServlet
DispatcherServlet
是 Spring MVC 的中央控制器,所有的 HTTP 请求都会先到达 DispatcherServlet
。它负责协调请求的处理流程。
在 DispatcherServlet
的 doDispatch()
方法中,定义了处理请求的核心逻辑:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;ModelAndView mv = null;Exception dispatchException = null;try {// 1. 获取处理器(Handler)mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// 2. 获取处理器适配器(HandlerAdapter)HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// 3. 执行前置拦截器(PreHandler Interceptor)if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 4. 执行处理器(Handler)逻辑,生成 ModelAndViewmv = ha.handle(processedRequest, response, mappedHandler.getHandler());// 5. 执行后置拦截器(PostHandler Interceptor)mappedHandler.applyPostHandle(processedRequest, response, mv);} catch (Exception ex) {dispatchException = ex;} catch (Throwable err) {dispatchException = new NestedServletException("Handler dispatch failed", err);} finally {// 6. 处理结果并渲染视图processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}
}
该方法的执行流程如下:
1、获取处理器:通过 getHandler() 方法,根据请求 URL 获取适当的处理器(Handler),通常是一个 Controller。
2、获取适配器:通过 getHandlerAdapter() 获取对应处理器的适配器(HandlerAdapter),负责调用具体的处理器方法。
3、执行前置拦截器:调用拦截器链的 applyPreHandle() 方法。
4、处理请求:调用 HandlerAdapter 的 handle() 方法,执行业务逻辑,并返回 ModelAndView 对象。
5、执行后置拦截器:调用拦截器链的 applyPostHandle() 方法。
6、渲染视图:调用 processDispatchResult() 进行结果处理,包括视图渲染。
2. HandlerMapping
HandlerMapping 负责根据请求 URL 映射到对应的处理器。Spring MVC 中常用的 HandlerMapping 实现有:
RequestMappingHandlerMapping:处理基于注解的映射(如 @RequestMapping)。
RequestMappingHandlerMapping 的核心逻辑是在 getHandlerInternal() 方法中根据请求查找相应的 Handler:
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {// 根据请求的 URL 查找对应的 HandlerMethodHandlerMethod handlerMethod = lookupHandlerMethod(request, getHandlerMethods());return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
这里的 lookupHandlerMethod() 方法根据请求 URL 查找已注册的处理方法,这些方法通常使用 @RequestMapping 注解。
3. HandlerAdapter
HandlerAdapter 负责调用处理器执行实际的业务逻辑。Spring MVC 通过 HandlerAdapter 将不同类型的处理器(如 Controller 接口实现类或注解控制器)适配成统一的调用方式。
RequestMappingHandlerAdapter 是最常用的 HandlerAdapter,其 handle() 方法如下:
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return invokeHandlerMethod(request, response, (HandlerMethod) handler);
}
invokeHandlerMethod() 方法负责调用实际的处理器方法,并生成 ModelAndView:
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {// 根据方法签名解析参数并调用处理方法ModelAndView mav = this.invokeAndHandle(webRequest, response, handlerMethod);return mav;
}
4. ViewResolver
ViewResolver 负责根据视图名解析实际的视图对象,通常是 JSP、Thymeleaf 等模板引擎生成的页面。Spring MVC 支持多种视图解析器,常见的是 InternalResourceViewResolver,它将逻辑视图名称解析为 JSP 文件路径。
InternalResourceViewResolver 的 resolveViewName() 方法:
@Override
protected View loadView(String viewName, Locale locale) throws Exception {// 根据视图名称解析 JSP 文件路径String url = getPrefix() + viewName + getSuffix();return new InternalResourceView(url);
}
5. ModelAndView
ModelAndView 是一个封装类,用于传递处理结果和视图信息。它包含模型数据和视图名称:
public class ModelAndView {private Object view;private Map<String, Object> model = new LinkedHashMap<>();
}
处理器方法执行后返回的 ModelAndView 对象会被 DispatcherServlet 传递给 ViewResolver 进行视图解析和渲染。
总结
Spring MVC 的核心流程通过 DispatcherServlet 调度请求,根据请求 URL 查找处理器,然后通过 HandlerAdapter 调用处理器执行业务逻辑,最终由 ViewResolver 解析视图并返回结果。这一系列的组件协作形成了强大的 Web 框架,既能支持注解驱动,也能扩展成多种视图技术。
可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。