天天看点

SpringMVC - DispatcherServlet

DispatcherServlet作用

DispatcherServlet 是前端控制器设计模式的实现,提供 Spring Web MVC 的集中访问点,而且负责职责的分派,而且与 Spring IoC 容器无缝集成,从而可以获得 Spring 的所有好处。DispatcherServlet 主要用作职责调度工作,本身主要用于控制流程,主要职责如下:

  • 文件上传解析,如果请求类型是 multipart 将通过 MultipartResolver 进行文件上传解析;
  • 通过 HandlerMapping,将请求映射到处理器(返回一个 HandlerExecutionChain,它包括一个处理器、多个 HandlerInterceptor 拦截器);
  • 通过 HandlerAdapter 支持多种类型的处理器(HandlerExecutionChain 中的处理器);
  • 通过 ViewResolver 解析逻辑视图名到具体视图实现;
  • 本地化解析;
  • 渲染具体的视图等;
  • 如果执行过程中遇到异常将交给 HandlerExceptionResolver 来解析。

两个容器

当 Spring 和 SpringMVC 同时出现,我们的项目中将存在两个容器,一个是 Spring 容器,另一个是 SpringMVC 容器,Spring 容器通过 ContextLoaderListener 来加载,SpringMVC 容器则通过 DispatcherServlet 来加载,这两个容器不一样:

SpringMVC - DispatcherServlet

从图中可以看出:

ContextLoaderListener 初始化的上下文加载的 Bean 是对于整个应用程序共享的,不管是使用什么表现层技术,一般如 DAO 层、Service 层 Bean;

DispatcherServlet 初始化的上下文加载的 Bean 是只对 Spring Web MVC 有效的 Bean,如 Controller、HandlerMapping、HandlerAdapter 等等,该初始化上下文应该只加载 Web相关组件。

  1. 为什么不在 Spring 容器中扫描所有 Bean?

    这个是不可能的。因为请求达到服务端后,找 DispatcherServlet 去处理,只会去 SpringMVC 容器中找,这就意味着 Controller 必须在 SpringMVC 容器中扫描。

  2. 为什么不在 SpringMVC 容器中扫描所有 Bean?

    这个是可以的,可以在 SpringMVC 容器中扫描所有 Bean。不写在一起,有两个方面的原因:

  3. 为了方便配置文件的管理.
  4. 在 Spring+SpringMVC+Hibernate 组合中,实际上也不支持这种写法.

继续阅读