一、背景及设计理念
在Spring Web诞生前,Java Web开发面临三大痛点:
- 过度耦合:Servlet API与业务代码深度绑定(如
HttpServletRequest/Response贯穿业务层) - 配置复杂:XML配置膨胀(Struts的struts-config.xml常达数千行)
- 扩展困难:现有框架封闭性强,定制需修改框架源码
典型案例:传统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 Core→Core Container(IoC 容器)Web MVC→Web CoreWeb REST→Web MVCWeb AOP→AOP(切面编程)
基于上述设计思路,我们可以将Spring Web模块的核心模块功能划分如下:
| 组件 | 核心职责 |
|---|---|
DispatcherServlet | 统一接收HTTP请求,协调所有组件处理流程 |
HandlerMapping | 根据请求URL匹配对应的处理器(Handler) |
HandlerAdapter | 统一调用不同类型的Handler |
Handler | 执行业务逻辑(通常为@Controller中的方法) |
HandlerMethodArgumentResolver | 将HTTP请求数据解析为Handler方法参数 |
HandlerMethodReturnValueHandler | 处理Handler返回值(如JSON转换/视图跳转) |
HandlerExceptionResolver | 统一处理控制器抛出的异常 |
1、核心组件详解
DispatcherServlet- 核心职责:前端控制器,所有请求必经入口
- 关键行为:
- 调用
HandlerMapping获取处理器链 - 通过
HandlerAdapter执行处理器 - 委托
HandlerExceptionResolver处理异常
- 调用
HandlerMapping- 核心职责:建立请求路径→处理器的映射关系
- 典型实现:
RequestMappingHandlerMapping(扫描@RequestMapping注解)
- 输出:
HandlerExecutionChain(含处理器+拦截器链)
HandlerAdapter- 核心职责:屏蔽处理器差异,提供统一调用接口
- 必要性:
- 适配多种处理器类型(如注解控制器 vs 传统Controller接口)
- 执行处理器前触发参数解析,后触发返回值处理
Handler- 核心形态:
@Controller中的业务方法(本质为HandlerMethod) - 核心任务:
- 接收解析后的参数
- 执行业务逻辑
- 返回数据或视图标识
- 核心形态:
HandlerMethodArgumentResolver- 核心职责:实现参数自动绑定
- 关键能力:
- 解析
@RequestParam,@PathVariable,@RequestBody等注解 - 将HTTP请求数据转化为Java对象
- 解析
HandlerMethodReturnValueHandler- 核心职责:处理控制器返回值
- 关键行为:
- 转换JSON响应(
@ResponseBody) - 处理视图跳转(
ModelAndView) - 处理流式响应(
InputStreamResource)
- 转换JSON响应(
HandlerExceptionResolver- 核心职责:捕获并处理控制器层异常
- 现代实现:
@ControllerAdvice+@ExceptionHandler(优先使用)- 可自定义错误响应数据结构
2、核心请求处理流程
关键说明:
- 省略视图解析(
ViewResolver)、文件上传(MultipartResolver)等非必要组件- 拦截器(
HandlerInterceptor)虽常用,但移除不影响核心流程执行- 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开发的深层矛盾。其核心架构思想体现为:
- 单一入口统一控制流:以
DispatcherServlet作为HTTP请求的中枢神经,彻底终结了Servlet时代分散处理的混乱局面。 - 组件化职责分离:将请求处理拆解为
HandlerMapping → HandlerAdapter → Controller → ViewResolver四大核心组件,形成清晰的处理链:- 映射层解耦URL与处理器绑定关系
- 适配层消除控制器接口差异
- 渲染层分离业务逻辑与视图技术
- 动态扩展生态:通过五大战略级扩展点构建自适应框架:
HandlerMapping支持RESTful/WebSocket等新型协议ArgumentResolver实现JWT/加密参数等定制解析HandlerInterceptor提供可插拔的横切关注点ViewResolver无缝集成Thymeleaf/React等渲染引擎ExceptionResolver统一异常处理范式
- 现代Web能力内化:
- 约定优于配置机制减少60%样板代码
- 内容协商实现同一接口多格式响应(JSON/XML/ProtoBuf)
- 异步处理支持背压控制与响应式流
- 全局异常处理打造抗脆弱API