前言
一直没弄明白 Spring MVC 中几个配置文件的关系,在这里梳理一下。
Spring MVC 配置
一、web.xml
DispatcherServlet 是整个框架的前端控制器,它是一个 Servlet,继承 HttpServlet。要告诉 DispatcherServlet 哪些请求需要它进行处理。
- 用 Java 代码配置 Spring
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
ServletRegistration.Dynamic registration = container.addServlet("example", new DispatcherServlet());
registration.setLoadOnStartup(1);
registration.addMapping("/example/*");
}
}
WebApplicationInitializer 是一个接口,能(1)初始化 Servlet 3 容器和(2)自动发现代码配置。
- XML 配置(相当于以上 Java 代码)
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping>
</web-app>
DispatcherServlet 转发请求之后的处理:
- HandlerMapping:处理请求和具体的控制类之间的映射关系。当请求到达 DispatcherServlet 之后,它去寻找具体的 HanderMapping 实例,获得对应当前请求的具体处理类 Controller。
- Controller:是对应 DispatcherServlet 的次级控制器,它对应某个具体请求的处理逻辑。
DispatcherServlet 拥有自己的 WebApplicationContext,它继承了所有根 WebApplicationContext 中的 bean。这些继承而来的 bean 可以被 Servlet 生命周期中的 bean 覆盖。
WebApplicationContext 不同于 ApplicationContext,它是 ApplicationContext 的扩展:
- 有解析 theme 的能力;
- 知道自己联系那个 Servlet。
二、[servlet-name]-servlet.xml
DispatcherServlet 初始化之后,Spring MVC 会在 WEB-INF
目录中找名为 [servlet-name]-servlet.xml 的配置文件,初始化其中的 bean;在这个配置文件中的 bean 会覆盖全局中的同名 bean。
实际上,也可以只存在 root 上下文,可以在 servlet init-param 参数中配置一个空的 contextConfigLocation。
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>