DispatcherServlet 为什么是 SpringMVC 的大脑?

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?