Spring MVC
字数: 0 字 时长: 0 分钟
简介
Spring MVC 是指 MVC(Model-View-Controller)模式,它将请求处理流程分为三层:模型层、视图层和控制层,用一种松耦合的方式将用户请求、业务逻辑和视图渲染分离开来。
Spring MVC 与 Spring 的关系
Spring 是底层基础,Spring MVC 构建在 Spring 核心之上,利用其提供的 IOC/DI、AOP 等功能来实现 Web 层的管理
工作流程
DispatcherServlet接收 HTTP 请求
DispatcherServlet (作为整个流程的调度中心)会首先接收到 HTTP 请求,然后调用 doDispatch() 执行分发调度逻辑

- 通过
HandlerMapping解析请求映射
DispatcherServlet 会首先去请求 HandlerMapping ,返回一个 HandlerExecutionChain 处理器执行链

其实这个 HandlerExecutionChain 对象包含了一个处理器和一系列拦截器

- 先通过
HandlerExecutionChain找到对应的HandlerAdapter,HandlerAdapter适配器反射执行实际处理器方法

实际执行之前,还会调用拦截器的 preHandle() 方法,返回为 true 的情况下,才会执行处理器方法,返回 ModelAndView

- 处理
ModelAndView
将 ModelAndView 委托给 ViewResolver 进行解析渲染

核心组件
DispatcherServlet
DispatcherServlet 是请求的入口与出口,也是整个流程的中央调度器,将请求委托给其他组件处理,比如 HandlerMapping、HandlerAdapter、ViewResolver 等
HandlerMapping
处理器映射器:负责解析请求,匹配请求 URL 对应的 Controller (或Handler)以及关联的拦截器 (HandlerInterceptor)链
HandlerAdapter
处理器适配器:适配器模式实现,负责调用目标 Handler 的相应方法(如@RequestMapping注解的方法),将请求参数、模型数据等进行封装,最后返回 ModelAndView 对象
Controller / Handler
实际处理器,负责接收 HandlerAdapter 传递过来的请求数据,执行业务逻辑(通常需要调用 Service 层)
ViewResolver / View
视图解析器与视图,将 Handler 返回的逻辑视图解析为具体的视图对象,并使用具体的视图模板进行渲染
HandlerExceptionResolver
处理器异常解析器,负责处理请求处理过程中发生的异常,可以将异常映射到特定的错误页面。常见的实现是 @ControllerAdvice + @ExceptionHandler
Spring 父子容器
父容器指的是 Spring 的根容器,主要管理应用程序的全局 Bean,如服务层(
Service)、数据访问层(DAO)等。通过ContextLoaderListener在应用启动时就初始化。子容器指的是 Spring MVC 中的
DispatcherServlet创建的容器,用于管理 Web 层相关 Bean (如Controller、HandlerMapping);在DispatcherServlet启动时初始化。
父子容器设计的好处
子容器可以访问父容器,父容器不能访问子容器。可以将业务逻辑和 Web 层分离,避免不必要的耦合。
拦截器
拦截器 (Interceptor)在 Spring MVC 的请求处理流程中起到类似过滤器的作用,但比过滤器更灵活。
- 过滤器:Servlet 规范定义,可以过滤所有请求,包括静态资源、Servlet、JSP、Controller 请求,类似门卫的角色
- 拦截器:Spring MVC 框架定义,只对 Controller 层请求起作用,提供更细粒度的控制,类似内部各流程关卡
拦截器提供三个核心方法:
preHandle():在控制器方法执行之前调用,如果返回false则不会调用控制器方法postHandle():在控制器方法执行之后,视图渲染之前调用。afterCompletion():在视图渲染完成后调用,用于清理资源或记录执行时间等
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在处理器方法调用前进行拦截
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 处理器方法执行后,但视图渲染前执行
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 视图渲染后执行
}
}@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns("/login", "/error"); // 排除某些路径
}
}Spring MVC 拦截器与 Spring AOP 拦截器的区别
Spring MVC 拦截器与 Spring AOP 拦截器其实完全不是一个东西!不要混淆
- AOP 拦截器基于动态代理实现,拦截的是方法调用
- MVC 拦截器通过实现
HandlerInterceptor接口定义拦截逻辑,用于增强 Web 层的 HTTP 请求流程
常用注解
请求映射相关
@RequestMapping、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping 处理相对应的请求
参数绑定相关
// 获取 URL 路径中的变量
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id)// 绑定单个字段
public List<User> search(@RequestParam String keyword)// 将请求体(JSON/XML)解析为 Java 对象
@PostMapping
public User createUser(@RequestBody User user)// 将请求参数绑定到对象 (常用于表单提交)
public String submitForm(@ModelAttribute UserForm form)// 处理文件上传
public String upload(@RequestPart("file") MultipartFile file)// 将 HTTP 请求头的值注入到控制器中
@GetMapping("/header-info")
public String getHeaderInfo(@RequestHeader("User-Agent") String userAgent) {
// 使用 userAgent 进行业务处理
return "headerInfoView";
}// 从 HTTP 请求的 Cookie 中提取值,注入到控制器方法的参数中
@GetMapping("/cookie-info")
public String getCookieInfo(@CookieValue("sessionId") String sessionId) {
// 使用 sessionId 进行业务处理
return "cookieInfoView";
}请求响应相关
// 将返回值直接写入响应体(代替视图渲染)
@ResponseBody
public User getUser()// 组合注解 = @Controller + @ResponseBody
@RestController
public class ApiController// 设置 HTTP 响应状态码
@ResponseStatus(HttpStatus.CREATED)
public void create()// 全局响应处理器 = @ControllerAdvice + @ResponseBody
@RestControllerAdvice
public class GlobalApiExceptionHandler {
@ExceptionHandler(ValidationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleValidationError(ValidationException ex) {
return new ErrorResponse("VALIDATION_FAILED", ex.getErrors());
}
}全局异常处理器
@ControllerAdvice 拦截所有 @Controller ,常用来进行全局异常统一处理
@ControllerAdvice
public class GlobalControllerAdvice {
// 全局异常处理器
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}
}跨域支持
@CrossOrigin 标注在类或方法上,启用跨域请求支持,不过一般都是使用全局跨域配置支持。
