前言

我们知道了Spring MVC的请求处理流程,但一个实际的项目是如何启动起来的呢?

下面将对Spring MVC的搭建原理进行分析。

一个基于Java代码驱动的Spring MVC包括:

  • 一个配置DispatcherServlet的类
  • 一个RootConfig类
  • 一个WebConfig类

版本:Spring Framework 4.3.x

1.配置DispatcherServlet到ServletContext

在典型的Servlet应用中,一个Web应用就是一个含有web.xml的war包,在xml中声明Servlet以及其它组件,这是一个很繁琐的配置文件。

在Servlet3.0以后,允许基于编程的Servlet应用配置,提供ServletContainerInitializer接口。Servlet容器会通过SPI机制加载其具体实现,Spring MVC在此基础上进行了封装,提供了AbstractAnnotationConfigDispatcherServletInitializer类供用户进行配置。

该类在启动时创建DispatcherServlet并注册到ServletContext中,创建Root应用上下文和Servlet应用上下文。提供以下两个方法,用于用户添加上下文配置:

protected abstract Class<?>[] getRootConfigClasses();
protected abstract Class<?>[] getServletConfigClasses();

2.RootConfig和WebConfig

区分两个上下文是Spring MVC设计之初考虑支持可能存在的多个DispatcherServlet,使它们的前端部分隔离,但共享服务层和数据层。

springMVC项目启动类_war包

在微服务的Spring Boot时代,只使用到了一个上下文。

springMVC项目启动类_MVC_02

3.@EnableWebMvc的原理

和其它Spring 集成框架一样,通过一个Enable注解,Spring就会完成相关组件的初始化和配置。这样的方式很惊艳,很实用。但就像魔法一样,人们不免会好奇背后的原理。

该注解通常用在WebConfig上,它只是简单的引入了一个配置类:

@Import(DelegatingWebMvcConfiguration.class)

DelegatingWebMvcConfiguration继承了WebMvcConfigurationSupportWebMvcConfigrationSupport驱动了Spring MVC项目,会完成Spring MVC的主要配置工作,包括创建DispatcherServlet的相关组件和以及这些组件的组件,如参数解析、消息转换等。

DelegatingWebMvcConfiguration会查找上下文的所有WebMvcConfigurer,委托给它们来完成扩展配置,WebMvcConfigurer定义了Spring MVC的扩展点。

可以使用WebMvcConfigurerAdapter便捷类,使用空实现避免繁琐的输入。

以上几个类的关系如下:

springMVC项目启动类_war包_03

总结

一个传统war包形式的Spring MVC项目骨架如下:

springMVC项目启动类_springMVC项目启动类_04

DispatherServlet由用户使用Spring相关API配置,Spring MVC的基础设施由@EnableWebMvc驱动,用户只需要使用WebMvcConfigurer来完成自定义功能实现。

到了Spring Boot时代,Spring Boot在@EnableWebMvc的基础之上进行了进一步配置,但WebMvcConfigurer依然是用户自定义Spring MVC的主要入口。