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存储和检索“输入”与“输出”的 FlashMapFlashMap 可用于在请求之间传递属性(通常是在重定向场景中)。参见 闪传属性 (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.