面试官:“简单的谈一下SpringMVC的工作流程?”

SpringMVC 是Java Web开发中最经典的框架之一,但你是否真正理解它的内部运行机制?当用户在浏览器输入一个URL时,SpringMVC是如何一步步处理请求并返回结果的?本文从源码层面解析SpringMVC的核心流程,用大白话+代码示例,带你彻底搞懂背后的设计思想!


一、SpringMVC工作流程总览

先看一张经典流程图:

核心步骤

  1. 用户发送请求 → 2. DispatcherServlet接收请求 → 3. HandlerMapping找Controller → 4. HandlerAdapter调用Controller方法 → 5. Controller处理请求 → 6. 返回ModelAndView → 7. ViewResolver解析视图 → 8. 渲染视图并返回响应


二、源码级分步解析

1. DispatcherServlet:请求的“总调度员”

核心作用:所有HTTP请求的入口,负责协调各组件工作。
源码入口DispatcherServletdoDispatch方法。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 1. 获取处理器映射(HandlerMapping)
    HandlerExecutionChain mappedHandler = getHandler(request);
    // 2. 获取处理器适配器(HandlerAdapter)
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    // 3. 调用Controller方法处理请求
    ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
    // 4. 解析视图并渲染
    processDispatchResult(request, response, mappedHandler, mv, dispatchException);
}

2. HandlerMapping:找到对应的Controller

核心作用:根据请求的URL,找到对应的Controller类和方法。
常见实现RequestMappingHandlerMapping(基于注解的映射)。

源码解析

// RequestMappingHandlerMapping 中查找匹配的HandlerMethod
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
    String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
    // 查找匹配的Controller方法
    HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
    return handlerMethod;
}

3. HandlerAdapter:调用Controller方法

核心作用:适配不同的Controller类型(如基于注解的@Controller、传统的Controller接口)。
常见实现RequestMappingHandlerAdapter(处理@RequestMapping方法)。

源码解析

// RequestMappingHandlerAdapter 调用Controller方法
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    // 反射调用Controller方法
    Object returnValue = invokeHandlerMethod(request, response, handlerMethod);
    // 封装结果为ModelAndView
    return getModelAndView(mavContainer, modelFactory, request);
}

4. Controller处理请求

核心作用:执行业务逻辑,返回数据或视图。
示例代码

@Controller
public class UserController {
    @GetMapping("/user")
    public String getUser(Model model) {
        model.addAttribute("user", new User("Spring"));
        return "user"; // 返回视图名
    }
}

5. ViewResolver:解析视图

核心作用:将Controller返回的视图名(如"user")解析为具体的视图对象(如JSP、Thymeleaf模板)。
常见实现InternalResourceViewResolver(解析JSP)。

源码解析

j

// InternalResourceViewResolver 解析视图名
protected View createView(String viewName, Locale locale) throws Exception {
    // 拼接JSP路径(如 "/WEB-INF/views/user.jsp")
    String url = getPrefix() + viewName + getSuffix();
    return new InternalResourceView(url);
}

6. 视图渲染

核心作用:将模型数据填充到视图中,生成最终的HTML响应。
源码解析

// AbstractView 渲染视图
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) {
    // 将Model数据暴露到Request属性中
    exposeModelAsRequestAttributes(model, request);
    // 转发到JSP页面
    request.getRequestDispatcher(url).forward(request, response);
}

三、核心组件协作流程图解

用户请求 → DispatcherServlet → HandlerMapping 
→ HandlerAdapter → Controller → ModelAndView 
→ ViewResolver → View → 响应

四、常见问题与避坑指南

问题1:为什么Controller方法返回String,就能跳转到页面?

答案

  • 返回的String会被ViewResolver解析为具体视图路径(如JSP)。

  • 例如返回"user"InternalResourceViewResolver会拼接为/WEB-INF/views/user.jsp

问题2:如何实现RESTful接口返回JSON?

答案

  • 使用@ResponseBody注解,配合HttpMessageConverter(如Jackson)将返回值转为JSON。

j

@GetMapping("/api/user")
@ResponseBody
public User getUser() {
    return new User("Spring");
}

问题3:HandlerMapping和HandlerAdapter的区别?

答案

  • HandlerMapping:负责找哪个Controller处理请求。

  • HandlerAdapter:负责实际调用Controller的方法。


五、SpringMVC的扩展点

  1. 拦截器(Interceptor)
    实现HandlerInterceptor接口,在请求处理前后插入逻辑(如权限校验)。

  2. 自定义ViewResolver
    实现ViewResolver接口,支持自定义视图类型(如PDF导出)。

  3. 异常处理器(@ExceptionHandler)
    统一处理Controller抛出的异常。


六、总结

  • 核心流程:DispatcherServlet协调各组件,从请求到响应的完整链路。

  • 关键组件:HandlerMapping、HandlerAdapter、ViewResolver各司其职。

  • 扩展能力:通过拦截器、自定义视图等灵活扩展功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙悟饭Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值