概述
在本文中,我们将介绍配置Spring框架的最新版本中可用的DispatcherServlet的三种不同方法:
- 我们将从XML配置和web.xml文件开始
- 然后,我们将Servlet声明从web.xml文件迁移到Java配置,但将所有其他配置保留为XML
- 最后,在重构的第三步(也是最后一步)中,我们将有一个100%由Java配置的项目
Maven核心配置
<dependencies>
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>4.0.4</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.14.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>exploded</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<configuration>
<!-- default: src/main/webapp/WEB-INF/web.xml-->
<!-- <webXml>src/main/webapp/WEB-INF/web.xml</webXml>-->
<!-- 兼容纯java配置, 忽略web.xml缺失的情况-->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
DispatcherServlet
Spring MVC的核心概念之一是DispatcherServlet。在Spring文档将其定义为:
HTTP请求处理程序/控制器的中央调度程序,例如,Web UI控制器或基于HTTP的远程服务导出程序的中央调度程序。派遣到已注册的处理程序以处理Web请求,从而提供便利的映射和异常处理功能。
基本上,DispatcherServlet是每个Spring MVC应用程序的入口。它的目的是拦截HTTP请求,并将其分派给知道如何处理的正确组件。
使用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块,我们声明了一个servlet:
- 被命名为
dispatcher
- 是org.springframework.web.servlet.DispatcherServlet的实例
- 将使用名为contextConfigLocation的参数进行初始化,该参数包含配置XML的路径
load-on-startup
是一个整数值,它指定要加载多个servlet的顺序。因此,如果您需要声明多个servlet,则可以定义将其初始化的顺序。标有较小整数的Servlet会先加载标有较大整数的Servlet。
现在,我们的servlet已配置完毕。第二步是声明servlet映射:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
通过Servlet映射,我们将其名称绑定到一个URL 模式,该URL模式指定它将处理的HTTP请求。
混合配置
随着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("/");
}
}
在此示例中,我们是:
- 实施WebApplicationInitializer接口
- 重写onStartup方法,我们创建一个新的XmlWebApplicationContext与作为传递相同的文件配置的contextConfigLocation在给servlet XML实例
- 然后,我们使用刚刚实例化的新上下文创建DispatcherServlet的实例。
- 最后,我们使用映射URL 模式注册servlet。
因此,我们使用Java声明了servlet并将其绑定到URL映射,但是我们将配置保留在单独的XML文件中:dispatcher-config.xml。
100%Java配置
通过这种方法,我们的servlet是用Java声明的,但是我们仍然需要一个XML文件来配置它。使用WebApplicationInitializer可以实现100%Java配置。
让我们看看如何重构前面的示例。
我们需要做的第一件事是为servlet创建应用程序上下文。
这次,我们将使用基于注释的上下文,以便我们可以使用Java和注释进行配置,并且无需使用XML文件(例如dispatcher-config.xml):
AnnotationConfigWebApplicationContext context
= new AnnotationConfigWebApplicationContext();
然后可以配置这种类型的上下文,以注册配置类:
context.register(AppConfig.class);
或设置将要扫描的整个程序包的配置类:
context.setConfigLocation("com.example.app.config");
现在,我们的应用程序上下文已创建,我们可以向ServletContext添加一个侦听器,该侦听器将加载上下文:
container.addListener(new ContextLoaderListener(context));
下一步是创建并注册我们的调度程序servlet:
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和注释配置具有许多优点。通常,它导致更短,更简洁的配置,并且注释为声明提供了更多上下文,因为它与它们所配置的代码位于同一位置。
但这并不总是一种优选甚至可能的方法。例如,某些开发人员可能更喜欢将他们的代码和配置分开,或者您可能需要使用无法修改的第三方代码。
结论
在本文中,我们介绍了在Spring 3.2+中配置DispatcherServlet的不同方法,您可以根据自己的偏好决定使用哪种方法。无论您选择什么,Spring都会根据您的决定进行调整。
参考
- Web4.0中web.xml头信息
- SpringMVC-DispatcherServlet工作流程及web.xml配置
- spring-xml配置
- applicationContext.xml和spring-servlet.xml的关系
- context-create
您可以在Gitee上找到本文的源代码。