
前置知识
这里主要讲一下SpringBoot里的各种组件和它们的作用与关系。
首先需要知道什么是SpringMVC。MVC就是Model-View-Controller。SpringBoot中内置了SpringMVC,并帮助你把一些繁琐的配置做好了(不需要写web.xml),使程序员只需要关注业务代码。
SpringMVC里有几个重要的部分,分别是DispatcherServlet,HandlerAdapter,Handler。下面简单介绍一下。
先看一张图,建立基本认识:
下面的内容是我问AI的,还挺清楚,大家有什么不懂的也可以直接问AI。
首先是HandlerAdapter和Handler:
在 Spring MVC 中,HandlerAdapter 和 Handler 是两个非常重要的概念,它们在请求处理过程中扮演着不同的角色。为了更好地理解它们的区别和作用,我们先分别解释一下这两个概念,然后再对比它们的不同之处。
Handler&HandlerAdapter
Handler(处理器)
- 定义:Handler 是一个接口,表示能够处理 HTTP 请求的对象。它通常是控制器(Controller)的一个实例,负责处理特定的 URL 请求。
- 功能:Handler 的主要职责是根据传入的请求参数执行相应的业务逻辑,并返回一个 ModelAndView 或其他类型的响应结果。
- 实现方式:
- 在 Spring MVC 中,最常见的是使用注解驱动的控制器(如 @Controller 或 @RestController),这些控制器类就是 Handler 的具体实现。
- 除了注解驱动的方式,Spring MVC 还支持基于接口的控制器(如 Controller 接口),但这种方式已经较少使用。
示例:
@Controller
public class MyController { @GetMapping(“/hello”)
public String hello(Model model) {
model.addAttribute(“message”, “Hello, World!”);
return “hello”; // 返回视图名称
}
}
在这个例子中,MyController 就是一个 Handler,它处理 /hello 路径的 GET 请求。
HandlerAdapter(处理器适配器)
- 定义:HandlerAdapter 是一个接口,它的作用是将不同类型的 Handler 统一为一种标准的处理方式。它负责调用具体的 Handler 并处理请求。
- 功能:HandlerAdapter 的主要职责是将请求交给合适的 Handler 处理,并将处理结果转换为 ModelAndView 或其他响应形式。它充当了框架与具体处理器之间的桥梁。
- 实现方式:
- Spring MVC 内置了多种 HandlerAdapter 实现,用于处理不同类型的 Handler。例如:
- RequestMappingHandlerAdapter:用于处理基于注解的控制器(如 @Controller、@RestController)。
- SimpleControllerHandlerAdapter:用于处理实现了 Controller 接口的传统控制器。
- HttpRequestHandlerAdapter:用于处理实现了 HttpRequestHandler 接口的处理器。
示例:
@RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
adapter.handle(request, response, handler);
在这个例子中,RequestMappingHandlerAdapter 是一个 HandlerAdapter,它负责调用注解驱动的控制器来处理请求。
Handler 和 HandlerAdapter 的区别
- 特性Handler(处理器)HandlerAdapter(处理器适配器)角色具体的请求处理者调用并适配不同的 Handler职责执行业务逻辑,处理请求将请求分发给合适的 Handler类型可以是注解驱动的控制器、命令对象等是一个适配器,负责统一处理流程数量可以有多个 Handler通常只有一个或少数几个 HandlerAdapter调用关系Handler 由 HandlerAdapter 调用HandlerAdapter 由 DispatcherServlet 调用
工作流程
- 在 Spring MVC 中,请求的处理流程如下:
1.请求到达:用户发起 HTTP 请求,请求被发送到 DispatcherServlet。
2.查找 Handler:DispatcherServlet 使用 HandlerMapping 来查找匹配的 Handler。
3.调用 HandlerAdapter:找到合适的 Handler 后,DispatcherServlet 会使用 HandlerAdapter 来调用该 Handler。
4.处理请求:HandlerAdapter 调用具体的 Handler,执行业务逻辑。
5.返回结果:Handler 处理完请求后,返回一个 ModelAndView 或其他类型的响应结果。
6.渲染视图:DispatcherServlet 根据返回的结果选择合适的视图进行渲染,并将响应返回给客户端。
总结
- Handler 是实际处理请求的对象,通常是控制器类,负责执行业务逻辑。
- HandlerAdapter 是一个适配器,它负责将请求分发给合适的 Handler,并确保所有类型的 Handler 都能以统一的方式被调用。
简单来说,HandlerAdapter 是一个中间层,它使得 Spring MVC 可以灵活地支持多种类型的 Handler,而不需要改变核心的请求处理流程。 - DispatcherServlet
然后是DispatcherServlet:
DispatcherServlet 是 Spring MVC 框架中的核心组件,它是整个 Web 请求处理流程的前端控制器(Front Controller)。所有的 HTTP 请求都会通过 DispatcherServlet 进行分发和处理。它负责协调 Spring MVC 的各个组件,完成从请求到响应的整个生命周期管理。
DispatcherServlet 的作用
DispatcherServlet 的作用
- 统一入口:DispatcherServlet 是 Spring MVC 的前端控制器,所有的 HTTP 请求都会被转发到这里。
- 请求分发:根据请求的 URL 和配置,DispatcherServlet 负责将请求分发给合适的处理器(Handler)。
- 组件协作:DispatcherServlet 协调了 Spring MVC 中的多个组件(如 HandlerMapping、HandlerAdapter、ViewResolver 等),确保请求能够被正确处理并返回响应。
DispatcherServlet 的工作流程
- 当一个 HTTP 请求到达时,DispatcherServlet 的主要工作流程如下:
1.接收请求: - 用户发起 HTTP 请求,请求被发送到 DispatcherServlet。
2.查找 Handler: - DispatcherServlet 使用 HandlerMapping 来查找能够处理该请求的 Handler(处理器)。
- HandlerMapping 根据请求的 URL、HTTP 方法等信息,匹配到对应的 Handler。
3.调用 HandlerAdapter: - 找到合适的 Handler 后,DispatcherServlet 使用 HandlerAdapter 来调用该 Handler。
- HandlerAdapter 是一个适配器,负责调用不同类型的 Handler 并统一返回结果。
4.执行业务逻辑: - Handler(通常是控制器类)执行具体的业务逻辑,并返回一个 ModelAndView 对象,其中包含模型数据和视图名称。
5.解析视图: - DispatcherServlet 使用 ViewResolver 将视图名称解析为具体的视图对象(如 JSP、Thymeleaf 等)。
6.渲染视图: - 视图对象根据模型数据进行渲染,生成最终的 HTML 页面或其他形式的响应内容。
7.返回响应: - 渲染完成后,DispatcherServlet 将响应内容返回给客户端。
DispatcherServlet 的初始化
- 在应用程序启动时,DispatcherServlet 会被初始化。它的初始化过程包括以下几个步骤:
1.加载 WebApplicationContext: - DispatcherServlet 会创建并加载一个独立的 Web 应用上下文(WebApplicationContext),用于存储与 Web 相关的 Bean。
2.注册组件: - 初始化过程中,DispatcherServlet 会注册一系列关键组件,例如:
- HandlerMapping:用于匹配请求和处理器。
- HandlerAdapter:用于调用处理器。
- ViewResolver:用于解析视图名称。
- 其他组件(如异常处理器、拦截器等)。
3.准备就绪: - 初始化完成后,DispatcherServlet 准备好接收和处理 HTTP 请求。
DispatcherServlet 的配置
在传统的 Spring MVC 项目中,DispatcherServlet 通常通过 web.xml 配置文件进行声明。例如:
1 | <servlet> |
在 Spring Boot 中,DispatcherServlet 的配置被自动简化,开发者不需要手动编写 web.xml 文件。Spring Boot 会自动配置 DispatcherServlet 并将其映射到 / 路径。
DispatcherServlet 的重要性
- 单一入口:DispatcherServlet 是整个 Spring MVC 请求处理流程的起点,所有的请求都必须经过它。
- 解耦设计:通过 DispatcherServlet,Spring MVC 实现了请求处理的解耦设计,使得框架可以灵活扩展。
- 可扩展性:开发者可以通过自定义 HandlerMapping、HandlerAdapter 或 ViewResolver 等组件,来实现特定的需求。
总结
DispatcherServlet 是 Spring MVC 的核心组件,作为前端控制器,它负责接收请求、分发请求、协调组件以及返回响应。它的存在使得 Spring MVC 的请求处理流程清晰且高效,同时提供了高度的灵活性和可扩展性。
流程分析
这里我们做分析的目的,主要是为了知道哪里添加了Interceptor,调用了Interceptor的preHandle方法。
如上图,直接在DispatcherServlet#doDispatch断点。箭头所指处, 就是开头那张图片的第一步,请求查询Handler,我们跟进。
继续跟进上图中的getHandler。
来到了AbstractHandlerMapping,我们继续跟进getHandlerExecutionChain。
这里就是add Interceptor的地方了。这下我们的目标其实也明确了。通过反射拿到AbstractHandlerMapping的adaptedInterceptor属性,向这个属性里添加我们的interceptor。那么怎么拿到当前代码环境下的,也就是当前上下文里的AbstractHandlerMapping呢?通过获取WebApplicationContext可以做到。
如上图,回到doDispatch,这里的mappedHandler就是一开始图片里的HandlerExectionChain。这里面包括两个interceptors和处理这个http请求需要用到的controller方法。
如上图,第一个箭头拿HandlerAdapter,第二个调用Interceptor中的preHandle方法,第三个就是调用controller中的对应方法。这里不讲了,可以自己跟进看一下。
下面这段可以作为反序列化sink的字节码动态加载。
1 | package interceptor; |