# 7.1.3　在 web.xml 中声明 DispatcherServlet

在典型的 Spring MVC 应用中，我们会需要 DispatcherServlet 和 ContextLoader-Listener。AbstractAnnotationConfigDispatcherServletInitializer 会自动注册它们，但是如果需要在 web.xml 中注册的话，那就需要我们自己来完成这项任务了。 如下是一个基本的 web.xml 文件，它按照传统的方式搭建了 Dispatcher-Servlet 和 ContextLoaderListener。

{% code title="程序清单 7.3　在 web.xml 中搭建 Spring MVC" %}

```markup
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
```

{% endcode %}

就像我在第 5 章曾经介绍过的，ContextLoaderListener 和 DispatcherServlet 各自都会加载一个 Spring 应用上下文。上下文参数 contextConfigLocation 指定了一个 XML 文件的地址，这个文件定义了根应用上下文，它会被 ContextLoader-Listener 加载。如程序清单 7.3 所示，根上下文会从 `/WEB-INF/spring/rootcontext.xml` 中加载 bean 定义。

DispatcherServlet 会根据 Servlet 的名字找到一个文件，并基于该文件加载应用上下文。在程序清单 7.3 中，Servlet 的名字是 appServlet，因此 Dispatcher-Servlet 会从 `/WEBINF/appServlet-context.xml` 文件中加载其应用上下文。

如果你希望指定 DispatcherServlet 配置文件的位置的话，那么可以在 Servlet 上指定一个 contextConfigLocation 初始化参数。例如，如下的配置中，DispatcherServlet 会从 `/WEB-INF/spring/appServlet/servlet-context.xml` 加载它的 bean：

```markup
<servlet>
  <servlet-name>appServlet</servlet-name>
  <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      /WEB-INF/spring/appServlet/servlet-context.xml
    </param-value>
  </init-parma>
  <load-on-startup>1</load-on-startup>
</servlet>
```

当然，上面阐述的都是如何让 DispatcherServlet 和 ContextLoaderListener 从 XML 中加载各自的应用上下文。但是，在本书中的大部分内容中，我们都更倾向于使用 Java 配置而不是 XML 配置。因此，我们需要让 Spring MVC 在启动的时候，从带有 @Configuration 注解的类上加载配置。

要在 Spring MVC 中使用基于 Java 的配置，我们需要告诉 DispatcherServlet 和 ContextLoaderListener 使用 AnnotationConfigWebApplicationContext，这是一 个 WebApplicationContext 的实现类，它会加载 Java 配置类，而不是使用 XML。要实现这种配置，我们可以设置 contextClass 上下文参数以及 DispatcherServlet 的初始化参数。如下的程序清单展现 了一个新的 web.xml，在这个文件中，它所搭建的 Spring MVC 使用基于 Java 的 Spring 配置：

{% code title="程序清单 7.4　设置 web.xml 使用基于 Java 的配置" %}

```markup
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >

  <context-param>
    <param-name>contextClass</param-name>
    <param-value>
      org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    </param-value>
  </context-param>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      com.habuma.spitter.config.RootConfig
    </param-value>
  </context-param>
  
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>contextClass</param-name>
      <param-value>
        org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
    </init-param>
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
        com.habuma.spitter.config.WebConfigConfig
      </param-value>
    </context-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
```

{% endcode %}

现在我们已经看到了如何以多种不同的方式来搭建 Spring MVC，那么接下来我们会看一下如何使用 Spring MVC 来处理文件上传。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://potoyang.gitbook.io/spring-in-action-v4/di-7-zhang-spring-mvc-de-gao-ji-ji-shu/untitled-5/untitled.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
