SpringMVC(结合源码浅析工作流程)

SpringMVC

概念

Spring MVC 是基于前端控制器(Front Controller)设计模式的 Web 框架,在 Web 应用中指一个统一的入口,用来接收所有客户端请求,并统一进行分发、处理。在 SpringMVC 中,前端控制器就是 DispatcherServlet,它的作用包括:

  • 接收所有请求
  • 调用对应的处理器(Controller)
  • 统一处理返回结果(视图渲染、数据响应等)

整体工作流程

工作流程图

用户发起请求

用户在浏览器输入一个地址,例如

复制代码
http://localhost:8080/api/seckill/execute

这个请求先被 Web 容器(Tomcat)接收,再被转交给 Spring MVC 的核心组件------DispatcherServlet。

DispatcherServlet进行调度

DispatcherServlet拿到请求之后会调用doDispatch(),DispatcherServlet接收到请求后会执行一系列方法,主要流程都集中的 doDispatch() 方法中

java 复制代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    ModelAndView mv = null;
    Exception dispatchException = null;
    try {
        // 1. 获取 HandlerExecutionChain(处理器执行链)
        mappedHandler = getHandler(processedRequest);
        
        // 2. 获取 HandlerAdapter(处理器适配器)
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        // 3. 调用前置拦截器(可选)
        if (!mappedHandler.applyPreHandle(processedRequest, response)) {
            return;
        }
        // 4. 执行 Controller 处理方法
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
        // 5. 调用后置拦截器(可选)
        mappedHandler.applyPostHandle(processedRequest, response, mv);
    }
    catch (Exception ex) {
        dispatchException = ex;
    }
    // 6. 处理视图渲染或异常
    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

下面依次介绍

查找处理器(handler)
java 复制代码
// mappedHandler = getHandler(processedRequest);
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;
}

遍历所有 HandlerMapping,逐个尝试匹配请求,找到对应的处理器(Controller)执行链

HandlerMapping是一个接口,常见的实现类有RequestMappingHandlerMapping处理基于注解的请求映射(如 @RequestMapping、@GetMapping 等)

获取对应的处理器适配器(HandlerAdapter)
java 复制代码
// 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;
      }
    }
  }
}

遍历所有 HandlerAdapter,判断当前适配器是否支持处理传入的 handler(Controller)

HandlerAdapter的作用在于解耦 DispatcherServlet 与具体 Controller 实现,使得通过同一个接口来调用不同类型的处理器(Controller)

调用 Controller 方法
java 复制代码
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

返回一个 ModelAndView 对象。

实际上是以反射的方式获取Method ,再Method.invoke()执行目标方法。

ModelAndView 是封装模型数据 和视图信息的对象。

java 复制代码
public class ModelAndView {

	private Object view;

	/** ModelMap继承了LinkedHashMap<String, Object>*/
	private ModelMap model;
}

Model(模型) :用于存放业务数据,类型是一个 LinkedHashMap<String, Object>

View(视图):视图名称或者视图对象(如 JSP),用来告诉框架最终渲染哪个页面

视图解析与渲染
java 复制代码
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
	->render(mv, request, response);
    ->View view;
    ->view = resolveViewName(viewName, mv.getModelInternal(), locale, request);//返回View对象
    ->view.render(mv.getModelInternal(), request, response);//渲染

根据mv中的view找到对应的ViewResolver,ViewResolver 的作用是

  • Controller 返回的是一个逻辑视图名(例如 "home")
  • ViewResolver 会根据配置,把逻辑视图名转换成具体视图文件的路径(例如 /WEB-INF/views/home.jsp)
  • 视图解析后由视图渲染器渲染页面并返回给客户端,就是将mv中的model数据填充到View对象中
相关推荐
Flynn Liang3 小时前
AI 应用的安全红线:Spring AI 下的 Prompt 注入防护、PII 脱敏、输出审计与密钥管理
人工智能·安全·spring·数据泄露·springai·prompt注入
QCoding3 小时前
企业级Agent Evaluation实战:Agent能跑就能上线?AI Agent到底怎么测?
后端·spring
海的透彻3 小时前
dockerfile如何快速构建容器(java服务)
java·开发语言
code2cat3 小时前
Java工具篇之Gradle:用任务图组织构建与交付
java·开发语言·单元测试·gradle
后台模板学习4 小时前
大模型 Prompt 工程在电商订单系统中的踩坑记录
java·python·prompt
w_zero_one4 小时前
算法--构造
java·数据结构·算法
SL_staff4 小时前
制造业订单交付崩盘?用四层协同框架重建交付可信度(技术实践)
java·产品·全栈
SL_staff5 小时前
打破风控迭代死循环:用决策编排重构业务与技术协作链路
java·产品·全栈
Mikko76 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
.Bryce.6 小时前
从零到一开发技术名词大全:从需求分析到 AI Agent 工程
java·网络·人工智能·agent·需求分析·agent评测