DispatcherServlet

Spring MVC 与许多其他 Web 框架一样,围绕前端控制器模式设计,其中一个中央 Servlet(即 DispatcherServlet)提供一个用于请求处理的共享算法,而实际工作由可配置的委托组件执行。此模型灵活并支持不同的工作流。

DispatcherServlet,就像任何 Servlet,都需要使用 Java 配置或在 web.xml 中按照 Servlet 规范进行声明和映射。而 DispatcherServlet 使用 Spring 配置来发现请求映射、视图解析、异常处理 and more 所需的委托组件。

以下 Java 配置示例注册并初始化 DispatcherServlet,它由 Servlet 容器自动检测(参见 Servlet Config):

  • Java

  • Kotlin

public class MyWebApplicationInitializer implements WebApplicationInitializer {

	@Override
	public void onStartup(ServletContext servletContext) {

		// Load Spring web application configuration
		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
		context.register(AppConfig.class);

		// Create and register the DispatcherServlet
		DispatcherServlet servlet = new DispatcherServlet(context);
		ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
		registration.setLoadOnStartup(1);
		registration.addMapping("/app/*");
	}
}
class MyWebApplicationInitializer : WebApplicationInitializer {

	override fun onStartup(servletContext: ServletContext) {

		// Load Spring web application configuration
		val context = AnnotationConfigWebApplicationContext()
		context.register(AppConfig::class.java)

		// Create and register the DispatcherServlet
		val servlet = DispatcherServlet(context)
		val registration = servletContext.addServlet("app", servlet)
		registration.setLoadOnStartup(1)
		registration.addMapping("/app/*")
	}
}

除了直接使用 ServletContext API 之外,您还可以扩展 AbstractAnnotationConfigDispatcherServletInitializer 并覆盖具体方法(请参阅 Context Hierarchy 下面的示例)。

对于以编程方式使用的情况,GenericWebApplicationContext 可作为 AnnotationConfigWebApplicationContext 的替代方案。有关详细信息,请参阅https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/support/GenericWebApplicationContext.html[GenericWebApplicationContext]javadoc。

以下 web.xml 配置示例注册并初始化 DispatcherServlet

<web-app>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/app-context.xml</param-value>
	</context-param>

	<servlet>
		<servlet-name>app</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value></param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>app</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>

</web-app>

Spring Boot 会遵循不同的初始化顺序。Spring Boot 不是介入 Servlet 容器的生命周期,而是使用 spring 配置来引导自身和嵌入式 Servlet 容器。在 spring 配置中检测到 FilterServlet 声明,并用 Servlet 容器对其进行登记。有关更多详细信息,请参阅 [Spring Boot 文档](https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.servlet.embedded-container)。