1. 概述

在这篇文章中,我们将探讨在最近的Spring框架版本中配置DispatcherServlet的三种不同方法:

  1. 我们首先从XML配置和web.xml文件开始。
  2. 接下来,我们将把Servlet声明从web.xml文件迁移到Java配置,但保留其他XML配置。
  3. 最后,在重构的第三步,我们将实现一个完全基于Java配置的项目。

2. DispatcherServlet

Spring MVC的核心概念之一是DispatcherServlet。根据Spring官方文档(Spring文档)的定义:

作为HTTP请求处理器/控制器的中央调度器,例如Web UI控制器或基于HTTP的远程服务提供者。它将请求分发给已注册的处理器进行处理,并提供方便的映射和异常处理功能。

基本上,DispatcherServlet是每个Spring MVC应用程序的入口点。它的作用是拦截HTTP请求,并将它们分发到能够处理它的正确组件。

3. 通过web.xml配置

如果你正在处理遗留的Spring项目,通常会发现XML配置,而在Spring 3.1之前,配置DispatcherServlet的唯一方法是在WEB-INF/web.xml文件中。在这种情况下,需要两个步骤。

让我们看一个示例配置:首先,我们需要声明Servlet:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

这段XML代码声明了一个名为“dispatcher”的Servlet:

  1. 它是org.springframework.web.servlet.DispatcherServlet的一个实例。
  2. 使用参数contextConfigLocation初始化,其中包含配置XML的路径。

load-on-startup是一个整数值,用于指定多个Servlet的加载顺序。如果需要声明多个Servlet,可以定义它们的加载顺序。标记为较小整数的Servlet将在标记为较大整数的Servlet之前加载。

现在Servlet已经配置好了。第二步是声明servlet-mapping

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

通过Servlet映射,我们根据其名称将其绑定到一个URL模式,该模式指定了将由它处理的HTTP请求。

4. 混合配置

随着Servlet API版本3.0的采用,web.xml文件变得可选,我们现在可以使用Java来配置DispatcherServlet

我们可以注册实现WebApplicationInitializer的Servlet。这相当于上述的XML配置:

public class MyWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext context = new XmlWebApplicationContext();
        context.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic dispatcher = container
          .addServlet("dispatcher", new DispatcherServlet(context));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

在这个例子中,我们:

  1. 实现WebApplicationInitializer接口。
  2. 重写onStartup方法,创建一个新的XmlWebApplicationContext,并使用与XML示例中传递给Servlet的相同文件进行配置。
  3. 然后,我们使用新创建的上下文实例化一个DispatcherServlet
  4. 最后,我们根据URL模式注册Servlet。

这样,我们使用Java声明了Servlet,并将其绑定到URL映射,但仍保留了配置在一个单独的XML文件中:dispatcher-config.xml

5. 100% Java配置

采用这种方法,我们的Servlet在Java中声明,但仍需要一个XML文件来配置它。使用WebApplicationInitializer,你可以实现100%的Java配置。

让我们看看如何重构之前的例子。

首先,我们需要为Servlet创建一个应用程序上下文。

这次我们将使用基于注解的上下文,以便我们可以使用Java和注解进行配置,从而消除对像dispatcher-config.xml这样的XML文件的需求:

AnnotationConfigWebApplicationContext context
  = new AnnotationConfigWebApplicationContext();

然后,可以通过注册配置类来配置这种类型的上下文:

context.register(AppConfig.class);

或者设置一个整个包,该包将扫描配置类:

context.setConfigLocation("com.example.app.config");

现在我们的应用程序上下文已经创建,可以在ServletContext上添加一个监听器来加载上下文:

container.addListener(new ContextLoaderListener(context));

接下来,创建并注册我们的DispatcherServlet

ServletRegistration.Dynamic dispatcher = container
  .addServlet("dispatcher", new DispatcherServlet(context));

dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");

现在,WebApplicationInitializer应该看起来像这样:

public class MyWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        AnnotationConfigWebApplicationContext context
          = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.example.app.config");

        container.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic dispatcher = container
          .addServlet("dispatcher", new DispatcherServlet(context));
        
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

Java和注解配置有许多优点。通常,它会导致更短、更简洁的配置,而注解提供了声明的更多上下文,因为它们与它们所配置的代码在同一位置。

但这并不总是首选的方式,甚至可能不可行。例如,一些开发人员可能更喜欢将代码和配置分开,或者你可能需要与第三方代码合作,而不能修改它。

6. 总结

在这篇文章中,我们探讨了在Spring 3.2+中配置DispatcherServlet的不同方式,选择哪种取决于你的偏好。无论你选择什么,Spring都会适应你的决定。

你可以在Github上找到这篇文章的源代码:这里这里


« 上一篇: Java周报,142