Servlet 3

在有了前面 Spring IoC 有关知识的基础上,我们可以进一步地了解 SpringMVC 的工作机制了。不过在此之前,为了形式上的统一,我们先介绍一下基于 Annotation 的 Servlet API。

前面的内容提到过,Spring 本身逐渐从 XML 转向了基于 Annotation 的配置,与之类似的,Servlet API 从 3.0 开始也支持了基于 Annotation 的配置。

在 Servlet 3 中,我们可以继承 ServletContainerInitializer 来实现替代 web.xml 的作用。Servlet 3 要求在 deploy 目录中加入 META-INF/services/javax.servlet.ServletContainerInitializer 文件,来指示 ServletContainerInitializer 的实现者,用于 Servlet 的初始化。

SpringMVC 已经帮我们做了这件事情,在 spring-web-4.3.9.RELEASE 这个 jar 里我们可以找到 javax.servlet.ServletContainerInitializer 这个文件,里面的内容是:

  1. org.springframework.web.SpringServletContainerInitializer

同时 SpringMVC 暴露出了自己的接口,名为 WebApplicationInitializer,通过这个接口我们可以进行类似 web.xml 的配置。

注意这一层封装,实际上是想把 Servlet API 和 Spring API 隔离开,在 SpringBoot 框架中我们会有更加深刻的体会。

创建一个新类 MyWebApplicationInitializer

  1. package com.skyline;
  2. import javax.servlet.*;
  3. import org.springframework.web.WebApplicationInitializer;
  4. import org.springframework.web.servlet.DispatcherServlet;
  5. public class MyWebApplicationInitializer implements WebApplicationInitializer {
  6. @Override
  7. public void onStartup(ServletContext container) {
  8. ServletRegistration.Dynamic registration = container.addServlet("MyFirstServletName", new DispatcherServlet());
  9. registration.setLoadOnStartup(1);
  10. registration.addMapping("/");
  11. }
  12. }

注意我们配置的内容,实际上和之前用过的 web.xml 是可以对应的:

  1. <servlet>
  2. <servlet-name>MyFirstServletName</servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  4. <load-on-startup>1</load-on-startup>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>MyFirstServletName</servlet-name>
  8. <url-pattern>/*</url-pattern>
  9. </servlet-mapping>

MyWebApplicationInitializer.class 部署到 Tomcat 目录,运行 Tomcat,可以得到和之前相同的结果。