Skip to content

特殊 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:

  1. 在上下文中查找:它会查看当前的 WebApplicationContext(以及父容器)中是否已经定义了特定类型的 Bean。
  2. 默认值(DispatcherServlet.properties):如果在配置中没找着,它会回退到 org.springframework.web.servlet 包下的 DispatcherServlet.properties 文件。该文件定义了每个特殊 Bean 类型的默认实现类。

3. HandlerMapping 和 HandlerAdapter 的“搭档”关系 ​

初学者经常弄混这两个组件。简单来说:

  • HandlerMapping (找人):它只负责回答“谁来接这个活?”。它返回的是一个 HandlerExecutionChain(里面包含控制器对象和拦截器)。
  • HandlerAdapter (干活):它负责真正的执行。因为控制器可能是各种形式的(可能是注解化的方法,也可能是传统的实现了接口的类),DispatcherServlet 不想知道具体的调用细节,于是让适配器去执行 handler 里的逻辑。这种模式极大地增强了框架的扩展性。

Based on Spring Framework.