DispatcherServlet 为什么是 SpringMVC 的大脑?
上一篇我们讲了:
Spring MVC 为什么只写一个注解就能接收请求?
当时留下了一个问题。
SpringMVC 已经通过 @RequestMapping 建立好了映射关系。
例如:
java
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/info")
public String info() {
return "success";
}
}
访问:
text
/user/info
SpringMVC 知道应该执行:
java
UserController#info()
但是新的问题来了。
谁来接收请求?
谁来找到这个 Controller?
谁来执行这个方法?
谁来把结果返回给浏览器?
总不能让所有组件互相调用吧。
所以 SpringMVC 引入了一个核心角色:
java
DispatcherServlet
很多文章都说:
DispatcherServlet 是 SpringMVC 的核心。
但我觉得更准确的说法是:
DispatcherServlet 是 SpringMVC 的大脑。
如果没有 DispatcherServlet
在 SpringMVC 出现之前。
很多项目都是直接写 Servlet。
java
public class UserServlet extends HttpServlet {
}
java
public class OrderServlet extends HttpServlet {
}
java
public class ProductServlet extends HttpServlet {
}
请求来了以后:
text
/user/*
↓
UserServlet
/order/*
↓
OrderServlet
/product/*
↓
ProductServlet
随着业务越来越复杂。
Servlet 数量越来越多。
整个系统会越来越难管理。
SpringMVC 是怎么解决的?
SpringMVC 的思路很简单。
既然每个请求都要处理。
那不如统一接收。
于是所有请求都会先进入:
java
DispatcherServlet
结构变成:
text
浏览器
↓
DispatcherServlet
↓
Controller
不管访问什么接口。
先经过 DispatcherServlet。
再由它决定下一步怎么处理。
DispatcherServlet 到底负责什么?
很多人以为:
DispatcherServlet 会直接处理业务。
其实不是。
它更像一个项目经理。
自己不干活。
负责安排别人干活。
它主要负责:
text
接收请求
↓
寻找处理器
↓
调用处理器
↓
处理结果
↓
返回响应
业务代码始终还是 Controller 在执行。
DispatcherServlet 做的是调度工作。
这也是它名字的由来。
Dispatcher:
text
调度
派发
分发
为什么 SpringMVC 必须这么设计?
因为统一入口有很多好处。
例如:
统一日志处理:
text
请求开始
请求结束
执行耗时
统一异常处理:
java
@ControllerAdvice
统一拦截器:
java
HandlerInterceptor
统一权限校验:
java
Spring Security
统一跨域处理:
java
CorsFilter
如果没有 DispatcherServlet。
这些功能都需要散落到各个 Controller 中。
维护成本会越来越高。
这其实是一种经典设计模式
它有一个专业名字:
Front Controller(前端控制器模式)
核心思想就是:
所有请求先进入统一入口。
再由入口协调后续流程。
结构如下:
text
浏览器
↓
DispatcherServlet
↓
HandlerMapping
HandlerAdapter
Controller
ViewResolver
以后新增组件。
只需要接入 DispatcherServlet 的流程即可。
整个框架扩展能力会非常强。
源码里它到底在哪?
DispatcherServlet 最核心的方法:
java
protected void doDispatch(
HttpServletRequest request,
HttpServletResponse response)
很多 SpringMVC 核心逻辑。
最终都会进入这里。
当请求到来时:
text
/user/info
最终执行:
java
doDispatch()
这里就像 SpringMVC 的总指挥室。
后续所有组件都会在这里被调度。
下一篇我们就从这里开始。
看看一次请求进入 SpringMVC 后到底经历了什么。
总结
很多人觉得 Controller 是 SpringMVC 的核心。
实际上 Controller 只是负责业务处理。
真正负责协调整个请求流程的,是 DispatcherServlet。
它不负责干活。
但负责安排所有组件协同工作。
所以:
Controller 是员工。
DispatcherServlet 才是 SpringMVC 的项目经理。
这也是为什么大家都说:
DispatcherServlet 是 SpringMVC 的大脑。
上一篇:
《一个 @RequestMapping 就能接收请求?Spring MVC 是怎么做到的》
下一篇:
《一次请求进来后到底发生了什么?》
如果让你自己实现一个简化版 SpringMVC,你会先设计 Controller,还是先设计 DispatcherServlet?