Spring Web 模块设计文档

82 阅读7分钟

一、背景及设计理念

在Spring Web诞生前,Java Web开发面临三大痛点:

  1. 过度耦合:Servlet API与业务代码深度绑定(如HttpServletRequest/Response贯穿业务层)
  2. 配置复杂:XML配置膨胀(Struts的struts-config.xml常达数千行)
  3. 扩展困难:现有框架封闭性强,定制需修改框架源码

典型案例:传统Servlet开发

问题暴露:业务逻辑/数据访问/视图渲染高度耦合,重复代码多,难以单元测试

public class UserServlet extends HttpServlet {
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
      // 1. 手动获取参数
      String id = req.getParameter("id");
      
      // 2. 手动new对象(无依赖注入)
      UserService service = new UserServiceImpl();
      User user = service.getUser(id);
      
      // 3. 手动渲染视图
      req.setAttribute("user", user);
      req.getRequestDispatcher("/user.jsp").forward(req, resp);
  }
}

二、设计目标

设计本质:Spring Web不是创造新技术,而是通过抽象层重新定义Web开发边界,在框架约束与开发者自由间找到平衡点。其核心理念可概括为:"以抽象解耦,以约定简化,以扩展赋能"

基于以上问题,聪明的码友很快可以提出以下方案:

  • 请求处理:接收 HTTP 请求并分发给对应的处理器(Controller)。
  • 依赖注入:通过 IoC 容器管理 Web 组件(如 Controller、Service)的生命周期。
  • MVC 架构:实现 Model-View-Controller 分离,支持视图渲染和业务逻辑解耦。
  • RESTful 支持:通过注解(如 @GetMapping@PostMapping)简化 REST API 开发。
  • 扩展性:支持自定义拦截器、异常处理器、模板引擎(如 Thymeleaf、JSP)。

1. 解耦至上原则

  • 问题解决:消除业务代码与Servlet API的强绑定
  • 实现方式
    • 抽象控制器层:用POJO类处理请求,不继承任何Servlet API
    • 引入方法参数解析:自动转换HTTP参数到Java对象
    • 统一返回值处理:支持多种返回类型(视图名/JSON/流等)
@RestController // 完全解耦的控制器
public class UserController {
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) { // 参数自动注入
        return userService.findById(id); // 直接返回领域对象
    }
}

2. 约定优于配置

  • 问题解决:消除冗余配置(如Struts的Action映射)
  • 实现方式
    • 注解驱动:@RequestMapping定义URL映射
    • 默认约定:类路径/WEB-INF/views/作为视图根目录
    • 自动扫描:@ComponentScan发现控制器
@Controller         // 自动识别为Web组件
@RequestMapping("/orders") // 类级别路径约定
public class OrderController {
    @PostMapping     // 默认映射POST方法
    public String create(Order order) {
        return "order_detail"; // 约定解析为/WEB-INF/views/order_detail.jsp
    }
}

3. 分层抽象体系

  • 问题解决:传统Web框架职责边界模糊

  • 分层设计在这里插入图片描述

  • 关键抽象

    • HandlerMapping:解耦请求与处理器的映射关系
    • HandlerAdapter:解耦处理器与执行逻辑
    • ViewResolver:解耦视图名称与渲染技术

4. 扩展开放机制

  • 问题解决:框架功能无法定制化扩展
  • 扩展点设计
扩展点应用场景实现示例
HandlerInterceptor权限校验/日志记录实现preHandle()方法
ArgumentResolver自定义参数解析解析JWT令牌到用户对象
ReturnValueHandler自定义返回值处理统一包装响应格式
ViewResolver支持新模板引擎集成Thymeleaf

5. 无缝整合核心容器

  • 问题解决:Web层与业务层对象管理割裂
  • 整合方案
    • 控制器作为Spring Bean管理
    • 依赖自动注入业务服务
    • AOP代理无缝生效
@Controller
public class ProductController {
    // 业务服务自动注入
    @Autowired 
    private ProductService productService;
    
    // 事务代理自动生效
    @Transactional
    @PostMapping("/products")
    public void create(Product product) {
        productService.save(product);
    }
}

三、核心模块划分

依赖关系

  • Web CoreCore Container(IoC 容器)
  • Web MVCWeb Core
  • Web RESTWeb MVC
  • Web AOPAOP(切面编程)

基于上述设计思路,我们可以将Spring Web模块的核心模块功能划分如下:

组件核心职责
DispatcherServlet统一接收HTTP请求,协调所有组件处理流程
HandlerMapping根据请求URL匹配对应的处理器(Handler)
HandlerAdapter统一调用不同类型的Handler
Handler执行业务逻辑(通常为@Controller中的方法)
HandlerMethodArgumentResolver将HTTP请求数据解析为Handler方法参数
HandlerMethodReturnValueHandler处理Handler返回值(如JSON转换/视图跳转)
HandlerExceptionResolver统一处理控制器抛出的异常

1、核心组件详解

  1. DispatcherServlet
    • 核心职责:前端控制器,所有请求必经入口
    • 关键行为
      • 调用HandlerMapping获取处理器链
      • 通过HandlerAdapter执行处理器
      • 委托HandlerExceptionResolver处理异常
  2. HandlerMapping
    • 核心职责:建立请求路径→处理器的映射关系
    • 典型实现
      • RequestMappingHandlerMapping(扫描@RequestMapping注解)
    • 输出HandlerExecutionChain(含处理器+拦截器链)
  3. HandlerAdapter
    • 核心职责屏蔽处理器差异,提供统一调用接口
    • 必要性
      • 适配多种处理器类型(如注解控制器 vs 传统Controller接口)
      • 执行处理器前触发参数解析,后触发返回值处理
  4. Handler
    • 核心形态@Controller中的业务方法(本质为HandlerMethod
    • 核心任务
      • 接收解析后的参数
      • 执行业务逻辑
      • 返回数据或视图标识
  5. HandlerMethodArgumentResolver
    • 核心职责实现参数自动绑定
    • 关键能力
      • 解析@RequestParam, @PathVariable, @RequestBody等注解
      • 将HTTP请求数据转化为Java对象
  6. HandlerMethodReturnValueHandler
    • 核心职责处理控制器返回值
    • 关键行为
      • 转换JSON响应(@ResponseBody
      • 处理视图跳转(ModelAndView
      • 处理流式响应(InputStreamResource
  7. HandlerExceptionResolver
    • 核心职责捕获并处理控制器层异常
    • 现代实现
      • @ControllerAdvice + @ExceptionHandler(优先使用)
      • 可自定义错误响应数据结构

2、核心请求处理流程

在这里插入图片描述

关键说明

  1. 省略视图解析(ViewResolver)、文件上传(MultipartResolver)等非必要组件
  2. 拦截器(HandlerInterceptor)虽常用,但移除不影响核心流程执行
  3. RESTful场景下,返回值处理器依赖HttpMessageConverter实现JSON转换(内置)

四、关键设计模式

1. 前端控制器模式

  • DispatcherServlet作为唯一入口点,提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。

2. 策略模式

// 不同策略实现相同接口
public interface ViewResolver {
    View resolveViewName(String viewName, Locale locale) throws Exception;
}

3. 适配器模式

// 间接
// org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
// org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter
// org.springframework.web.servlet.HandlerAdapter
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements HandlerAdapter {
    public boolean supports(Object handler) {
        return handler instanceof HandlerMethod;
    }
}

4. 模板方法模式

@Override
@Nullable
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws Exception {

    if (HttpMethod.OPTIONS.matches(request.getMethod())) {
        response.setHeader(HttpHeaders.ALLOW, getAllowHeader());
        return null;
    }

    // Delegate to WebContentGenerator for checking and preparing.
    checkRequest(request);
    prepareResponse(response);

    // Execute handleRequestInternal in synchronized block if required.
    if (this.synchronizeOnSession) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 会话锁
            Object mutex = WebUtils.getSessionMutex(session);
            synchronized (mutex) {
                // 子类实现
                return handleRequestInternal(request, response);
            }
        }
    } 	
    return handleRequestInternal(request, response);
}

5. 拦截器模式

public interface HandlerInterceptor {
    default boolean preHandle(...) { /* 前置处理 */ }
    default void postHandle(...) { /* 后置处理 */ }
    default void afterCompletion(...) { /* 后置处理 */ }
}

五、扩展机制与高级特性

1. 自定义组件扩展

// 自定义视图解析器
public class CustomViewResolver implements ViewResolver, Ordered {
    @Override
    public View resolveViewName(String viewName, Locale locale) {
        if (viewName.startsWith("custom:")) {
            return new CustomView(viewName.substring(7));
        }
        return null;
    }
}

// 注册自定义组件
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.viewResolver(new CustomViewResolver());
    }
}

2. 参数解析高级特性

// 自定义参数解析器
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(User.class);
    }
    
    public Object resolveArgument(...) {
        String userId = request.getParameter("userId");
        return userService.findById(userId);
    }
}

// 注册参数解析器
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new UserArgumentResolver());
    }
}

3. RESTful支持

@RestController
@RequestMapping("/api/users")
public class UserApiController {
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User saved = userService.save(user);
        return ResponseEntity.created(URI.create("/users/"+saved.getId())).body(saved);
    }
}

4. 异步处理

@GetMapping("/async")
public CompletableFuture<String> asyncProcessing() {
    return CompletableFuture.supplyAsync(() -> {
        // 长时间处理
        return "result";
    });
}

六、设计总结

Spring Web框架的设计本质是通过分层抽象与开放扩展解决传统Web开发的深层矛盾。其核心架构思想体现为:

  1. 单一入口统一控制流:以DispatcherServlet作为HTTP请求的中枢神经,彻底终结了Servlet时代分散处理的混乱局面。
  2. 组件化职责分离:将请求处理拆解为HandlerMapping → HandlerAdapter → Controller → ViewResolver四大核心组件,形成清晰的处理链
    • 映射层解耦URL与处理器绑定关系
    • 适配层消除控制器接口差异
    • 渲染层分离业务逻辑与视图技术
  3. 动态扩展生态:通过五大战略级扩展点构建自适应框架
    • HandlerMapping支持RESTful/WebSocket等新型协议
    • ArgumentResolver实现JWT/加密参数等定制解析
    • HandlerInterceptor提供可插拔的横切关注点
    • ViewResolver无缝集成Thymeleaf/React等渲染引擎
    • ExceptionResolver统一异常处理范式
  4. 现代Web能力内化
    • 约定优于配置机制减少60%样板代码
    • 内容协商实现同一接口多格式响应(JSON/XML/ProtoBuf)
    • 异步处理支持背压控制与响应式流
    • 全局异常处理打造抗脆弱API

扫码_搜索联合传播样式-标准色版.png