DispatcherServlet

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

Spring MVC, as many other web frameworks, is designed around the front controller pattern where a central Servlet, the DispatcherServlet, provides a shared algorithm for request processing, while actual work is performed by configurable delegate components. This model is flexible and supports diverse workflows.

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

The DispatcherServlet, as any Servlet, needs to be declared and mapped according to the Servlet specification by using Java configuration or in web.xml. In turn, the DispatcherServlet uses Spring configuration to discover the delegate components it needs for request mapping, view resolution, exception handling, and more.

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

The following example of the Java configuration registers and initializes the DispatcherServlet, which is auto-detected by the Servlet container (see 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 下面的示例)。

In addition to using the ServletContext API directly, you can also extend AbstractAnnotationConfigDispatcherServletInitializer and override specific methods (see the example under Context Hierarchy).

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

For programmatic use cases, a GenericWebApplicationContext can be used as an alternative to AnnotationConfigWebApplicationContext. See the GenericWebApplicationContext javadoc for details.

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

The following example of web.xml configuration registers and initializes the 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)。

Spring Boot follows a different initialization sequence. Rather than hooking into the lifecycle of the Servlet container, Spring Boot uses Spring configuration to bootstrap itself and the embedded Servlet container. Filter and Servlet declarations are detected in Spring configuration and registered with the Servlet container. For more details, see the Spring Boot documentation.