特殊 Bean 类型 (Special Bean Types)
DispatcherServlet 将请求处理和响应渲染的工作委托给其特定的 特殊 Bean。所谓“特殊 Bean”,是指由 Spring 管理的、实现了框架特定契约(Contract)的 Object 实例。这些 Bean 通常都有对应的内置实现,但你可以根据需要自定义它们的属性,或者对它们进行扩展或替换。
下表列出了 DispatcherServlet 会自动检测到的特殊 Bean:
| Bean 类型 | 说明 |
|---|---|
HandlerMapping | 将请求映射到处理器(Handler),并包含一组用于预处理和后处理的 拦截器 (interceptors)。映射基于某些标准,具体细节取决于 HandlerMapping 的实现。两个主要的实现是 RequestMappingHandlerMapping(支持 @RequestMapping 注解的方法)和 SimpleUrlHandlerMapping(维护 URI 路径模式到处理器的显式注册)。 |
HandlerAdapter | 帮助 DispatcherServlet 调用映射到请求的处理器,无论该处理器是如何实际调用的。例如,调用一个通过注解声明的控制器需要解析相关的注解。HandlerAdapter 的主要目的是屏蔽 DispatcherServlet 内部处理这些细节的复杂性。 |
HandlerExceptionResolver | 处理异常的策略,可能将异常映射到处理器、HTML 错误视图或其他目标。参见 异常处理。 |
ViewResolver | 将处理器返回的基于逻辑名称的 String 视图映射到实际的 View 实例,以便渲染响应。参见 视图解析 和 视图技术。 |
LocaleResolver, LocaleContextResolver | 解析客户端正在使用的 Locale(区域),以及可能的时区,以便提供国际化的视图。参见 本地化 (Locale)。 |
MultipartResolver | 用于解析多部分请求(例如浏览器表单文件上传)的抽象。参见 分部分解析器 (Multipart Resolver)。 |
FlashMapManager | 存储和检索“输入”与“输出”的 FlashMap。FlashMap 可用于在请求之间传递属性(通常是在重定向场景中)。参见 闪传属性 (Flash Attributes)。 |
补充教学
1. 为什么叫“特殊” Bean?
在 Spring 中,大多数 Bean 是由你定义的业务组件(Service, Repository)。而这些特殊 Bean 是 Spring MVC 框架的骨架。
- 自动发现:你不需要通过特殊的 API 去注册它们,只需要将它们定义在 Spring 上下文中(或者使用默认实现),
DispatcherServlet在启动时就会通过反射和扫描自动“认出”它们。 - 策略模式:Spring MVC 实际上是一堆“策略”的组合。例如,如果你想换一种文件上传方式,你只需要替换
MultipartResolver的实现,而不需要修改DispatcherServlet的代码。
2. 它们是如何被发现的?
当 DispatcherServlet 初始化时,它会按以下顺序寻找这些 Bean:
- 在上下文中查找:它会查看当前的
WebApplicationContext(以及父容器)中是否已经定义了特定类型的 Bean。 - 默认值(DispatcherServlet.properties):如果在配置中没找着,它会回退到
org.springframework.web.servlet包下的DispatcherServlet.properties文件。该文件定义了每个特殊 Bean 类型的默认实现类。
3. HandlerMapping 和 HandlerAdapter 的“搭档”关系
初学者经常弄混这两个组件。简单来说:
HandlerMapping(找人):它只负责回答“谁来接这个活?”。它返回的是一个HandlerExecutionChain(里面包含控制器对象和拦截器)。HandlerAdapter(干活):它负责真正的执行。因为控制器可能是各种形式的(可能是注解化的方法,也可能是传统的实现了接口的类),DispatcherServlet不想知道具体的调用细节,于是让适配器去执行handler里的逻辑。这种模式极大地增强了框架的扩展性。