Spring MVC

基础内容介绍

Spring MVC框架教程及使用指南

一、Spring MVC核心概念
  1. MVC架构模式

    Spring MVC基于模型-视图-控制器设计模式:

    • 模型(Model) :封装业务数据(如MapModel对象或POJO类)
    • 视图(View):渲染模型数据(支持JSP、Thymeleaf等模板)
    • 控制器(Controller):处理用户请求并协调模型与视图
  2. 核心组件

    • 前端控制器(DispatcherServlet):中央调度器,接收所有HTTP请求并分发
    • 处理器映射(HandlerMapping):将URL映射到对应的Controller
    • 视图解析器(ViewResolver) :将逻辑视图名解析为具体视图技术(如/WEB-INF/views/success.jsp
二、快速入门配置
  1. Maven依赖

    xml 复制代码
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.18</version>
    </dependency>
  2. web.xml配置(前端控制器)

    xml 复制代码
    <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-mvc.xml</param-value>
      </init-param>
    </servlet>
    <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
  3. Spring MVC配置文件(spring-mvc.xml)

    xml 复制代码
    <!-- 启用注解驱动 -->
    <mvc:annotation-driven/>
    
    <!-- 控制器扫描 -->
    <context:component-scan base-package="com.example.controller"/>
    
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/views/"/>
      <property name="suffix" value=".jsp"/>
    </bean>
三、控制器开发详解
java 复制代码
@Controller
public class UserController {
  
  // 处理GET请求 /users
  @GetMapping("/users")
  public String listUsers(Model model) {
    List<User> users = userService.getAllUsers();
    model.addAttribute("userList", users);  // 添加模型数据
    return "user/list";  // 对应 /WEB-INF/views/user/list.jsp
  }

  // 处理POST表单提交
  @PostMapping("/register")
  public String register(@ModelAttribute User user) {
    userService.save(user);
    return "redirect:/success";  // 重定向
  }

  // RESTful风格示例
  @GetMapping("/api/users/{id}")
  @ResponseBody
  public User getUser(@PathVariable Long id) {
    return userService.findById(id);
  }
}
四、关键注解说明
注解 作用 示例
@Controller 声明控制器类 @Controller public class XxxController
@RequestMapping 映射请求URL @RequestMapping("/path")
@RequestParam 获取请求参数 @RequestParam("name") String username
@PathVariable 获取URL路径变量 @PathVariable("id") Long userId
@ModelAttribute 绑定表单数据 @ModelAttribute User user
@ResponseBody 直接返回数据(非视图) 用于REST API
五、数据处理流程
  1. 用户请求 → DispatcherServlet接收请求
  2. HandlerMapping查找Controller → 调用对应方法
  3. 方法处理业务逻辑 → 返回视图名称或数据
  4. ViewResolver解析视图 → 渲染模型数据
  5. 返回HTTP响应到客户端
六、高级特性
  1. 拦截器(Interceptor)

    java 复制代码
    public class AuthInterceptor implements HandlerInterceptor {
      @Override
      public boolean preHandle(HttpServletRequest request, 
                              HttpServletResponse response, 
                              Object handler) {
        // 登录验证逻辑
        if (!isLogin(request)) {
          response.sendRedirect("/login");
          return false;
        }
        return true;
      }
    }

    配置:

    xml 复制代码
    <mvc:interceptors>
      <bean class="com.example.AuthInterceptor"/>
    </mvc:interceptors>
  2. 异常统一处理

    java 复制代码
    @ControllerAdvice
    public class GlobalExceptionHandler {
      @ExceptionHandler(Exception.class)
      public String handleError(Model model, Exception ex) {
        model.addAttribute("error", ex.getMessage());
        return "error-page";
      }
    }
七、最佳实践建议
  1. 分层架构:Controller只负责流程调度,业务逻辑放在Service层
  2. 使用RESTful风格 :资源化URL设计(如GET /api/users
  3. 参数校验 :结合@Valid注解验证表单数据
  4. 静态资源处理 :配置<mvc:resources location="/static/" mapping="/static/**"/>
思维导图

相关学习资源


相关源码及原理示例

Spring MVC 注解详解、框架原理与源码解析

基于引用[1][2][4]的深度分析,结合源码剖析Spring MVC核心机制:


一、核心注解深度解析

1. 请求映射注解
java 复制代码
@RestController
@RequestMapping("/api")
public class UserApiController {
    
    // 精准匹配GET请求(源码:RequestMappingInfo.Builder)
    @GetMapping(value = "/users/{id}", 
                headers = "X-API-Version=1",
                consumes = MediaType.APPLICATION_JSON_VALUE)
    public User getUser(@PathVariable("id") Long userId) { ... }
}
  • @RequestMapping
    底层通过RequestMappingHandlerMapping构建RequestMappingInfo对象,存储URL/方法/头信息等元数据
  • @PathVariable
    PathVariableMethodArgumentResolver解析,通过NamedValueInfo提取URI模板变量(源码:AbstractNamedValueMethodArgumentResolver
2. 参数绑定注解
java 复制代码
@PostMapping("/register")
public ResponseEntity<?> register(
    @Valid @ModelAttribute User user,  // 对象绑定
    @RequestParam("source") String regSource, // 查询参数
    @RequestHeader("User-Agent") String ua // 请求头
) { ... }
  • @ModelAttribute
    ModelAttributeMethodProcessor通过WebDataBinder实现数据绑定(源码:DataBinder.bind()
  • @RequestParam
    RequestParamMethodArgumentResolverServletRequest.getParameterMap()获取值

二、框架核心原理分析

1. 请求处理流程源码解析(引用[2]流程图实现)

Client DispatcherServlet HandlerMapping HandlerAdapter Controller ViewResolver View HTTP Request getHandler() HandlerExecutionChain getHandlerAdapter() invokeHandlerMethod() ModelAndView ModelAndView resolveViewName() View render() HTTP Response Client DispatcherServlet HandlerMapping HandlerAdapter Controller ViewResolver View

2. 关键源码节点
  1. DispatcherServlet初始化

    java 复制代码
    // 源码:DispatcherServlet.initStrategies()
    protected void initStrategies(ApplicationContext context) {
      initHandlerMappings(context);    // 初始化HandlerMapping
      initHandlerAdapters(context);    // 初始化HandlerAdapter
      initViewResolvers(context);      // 初始化ViewResolver
    }
  2. 处理器适配器调用 (引用[4])
    RequestMappingHandlerAdapter.invokeHandlerMethod()核心流程:

    java 复制代码
    // 源码:RequestMappingHandlerAdapter
    protected ModelAndView invokeHandlerMethod(...) {
      // 1. 数据绑定
      WebDataBinderFactory binderFactory = getDataBinderFactory(...);
      // 2. 参数解析
      ServletInvocableHandlerMethod invocableMethod = ...;
      invocableMethod.invokeAndHandle(...); // 执行Controller方法
    }

三、高级机制源码剖析

1. 拦截器实现原理
java 复制代码
// 源码:HandlerExecutionChain
public boolean applyPreHandle(...) throws Exception {
  for (int i = 0; i < this.interceptorList.size(); i++) {
    HandlerInterceptor interceptor = this.interceptorList.get(i);
    if (!interceptor.preHandle(request, response, this.handler)) {
      return false; // 拦截请求
    }
  }
  return true;
}
2. 参数验证流程
java 复制代码
@PostMapping("/users")
public void createUser(@Valid @RequestBody User user) { ... }
  • MethodValidationInterceptor触发(Spring 5.3+)
  • 底层通过ValidatorImpl执行JSR-380规范验证

四、最佳实践与避坑指南

  1. 注解使用陷阱

    • @RequestMapping的路径冲突由RequestMappingInfo.compareTo()解决(按精度排序)
    • @RequestParam(required=false)必须与Optional或默认值搭配
  2. 性能优化点

    • 避免在Controller中直接操作HttpServletResponse(破坏MVC结构)
    • 使用@ControllerAdvice统一异常处理替代每个Controller的try-catch

五、调试与源码学习建议

  1. 核心断点位置

    • DispatcherServlet.doDispatch()(请求入口)
    • RequestMappingHandlerMapping.getHandlerInternal()(映射查找)
    • HandlerMethodArgumentResolverComposite.resolveArgument()(参数解析)
  2. 官方源码入口
    Spring MVC GitHub源码

思维导图
相关推荐
C+-C资深大佬19 分钟前
C++ 性能优化 专业详解
java·c++·性能优化
程序员老乔20 分钟前
Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(三):虚拟线程2.0,电商秒杀场景下的并发革命
java·开发语言·spring boot
weixin_4041576821 分钟前
Java高级面试与工程实践问题集(四)
java·开发语言·面试
cyforkk29 分钟前
Spring AOP 核心揭秘:ProceedingJoinPoint 与反射机制详解
java·python·spring
无限进步_33 分钟前
【C++】单词反转算法详解:原地操作与边界处理
java·开发语言·c++·git·算法·github·visual studio
wyiyiyi36 分钟前
【线性代数】对偶空间与矩阵转置及矩阵分解(Java讲解)
java·线性代数·支持向量机·矩阵·数据分析
你这个代码我看不懂40 分钟前
磁盘的存储原理
java
PyAIGCMaster1 小时前
开发了一个全自动接入wordpress的saas发文章的网站,记录一下如何实现,有需要的朋友联系。
java·开发语言·数据库
研究点啥好呢1 小时前
3月21日GitHub热门项目推荐|攻守兼备,方得圆满
java·c++·python·开源·github
椰猫子1 小时前
JDK概述、Maven概述、IDEA概述、常见注解、 Spring Boot + SSM概述、RESTFul编程风格概述
java·ide·intellij-idea