1. 概述
在这篇文章中,我们将探讨在最近的Spring框架版本中配置DispatcherServlet的三种不同方法:
- 我们首先从XML配置和
web.xml
文件开始。 - 接下来,我们将把Servlet声明从
web.xml
文件迁移到Java配置,但保留其他XML配置。 - 最后,在重构的第三步,我们将实现一个完全基于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:
- 它是
org.springframework.web.servlet.DispatcherServlet
的一个实例。 - 使用参数
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("/");
}
}
在这个例子中,我们:
- 实现
WebApplicationInitializer
接口。 - 重写
onStartup
方法,创建一个新的XmlWebApplicationContext
,并使用与XML示例中传递给Servlet的相同文件进行配置。 - 然后,我们使用新创建的上下文实例化一个
DispatcherServlet
。 - 最后,我们根据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都会适应你的决定。