Spring MVC启动过程 - DispatcherServlet

本文详细介绍了SpringMVC框架的核心组件DispatcherServlet的工作原理及初始化过程。从服务器启动到DispatcherServlet实例创建,再到其如何通过配置文件加载组件,最终成为处理HTTP请求的Servlet。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.概述

1. springMVC的核心是DispatcherServlet,它负责截获请求并将其分派给相对应的处理器处理。
2. DispatcherServlet说到底是个Servlet,有init(ServletConfig)、service()、destroy()等方法:
  •  服务器启动时会创建DispatcherServlet实例,这时DispatcherServlet实例还是只是一个普通对象
  •  触发init(ServletConfig)方法,使DispatcherServlet实例变成一个真正的Servlet,在init(ServletConfig)调用init()初始化一些东西
  • DispatcherServlet的父类HttpServletBean重写的init()方法,初始化Spring MVC配置文件/WEB-INF/spring/applicationContext.xml的信息
  • 客户请求到来触发service()方法,DispatcherServlet实例负责分发请求到不同的控制器
3. 参考:Spring MVC启动整体过程

二.初始化DispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">  
<web-app>  
    <!-- 配置Spring Bean定义文件-->  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>/WEB-INF/spring/applicationContext.xml</param-value>  
    </context-param>  
      
    <!-- Spring初始化监听器:web应用启动时,监听器初始化Spring -->  
    <listener>   
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>   
    </listener>   
      
    <!-- 初始化<span style="font-family: tahoma, arial, 宋体;">spring前端控制器</span>DispatcherServlet -->  
    <servlet>   
        <servlet-name>mvc-dispatcher</servlet-name>   
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>   
    <load-on-startup>1</load-on-startup>   
    </servlet>   
                                      
    <servlet-mapping>   
        <servlet-name>mvc-dispatcher</servlet-name>   
        <url-pattern>/*.do</url-pattern>   
    </servlet-mapping>   
    
</web-app>

2.1 web服务器启动DispatcherServlet

初始化DispatcherServlet实例
public DispatcherServlet() {
		super();
	}

2.2 调用Servlet的init(ServletConfig)

2.1中只是创建了一个普通的对象,DispatcherServlet要变成一个真正的Servlet,还需要执行init(ServletConfig)方法
// javax.servlet.GenericServlet
public void init(ServletConfig config throws ServletException {
	this.config = config;
	init();
}
子类重写init()方法,加载DispatcherServlet的init-param初始化参数
// org.springframework.web.servlet.HttpServletBean
@Override
public final void init() throws ServletException {
	if (logger.isDebugEnabled()) {
		logger.debug("Initializing servlet '" + getServletName() + "'");
	}
	// Set bean properties from init parameters.
	try {
		PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
		ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
		bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
		initBeanWrapper(bw);
		bw.setPropertyValues(pvs, true);
	}
	catch (BeansException ex) {
		logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
		throw ex;
	}

	// Let subclasses do whatever initialization they like.
	initServletBean();

	if (logger.isDebugEnabled()) {
		logger.debug("Servlet '" + getServletName() + "' configured successfully");
	}
}
子类重写initServletBean()方法,创建DispatcherServlet实例的上下文WebApplicationContext
// org.springframework.web.servlet.FrameworkServlet
@Override
protected final void initServletBean() throws ServletException {
	getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
	if (this.logger.isInfoEnabled()) {
		this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
	}
	long startTime = System.currentTimeMillis();

	try {
		// 创建上下文
		this.webApplicationContext = initWebApplicationContext();
		initFrameworkServlet();
	}
	catch (ServletException ex) {
		this.logger.error("Context initialization failed", ex);
		throw ex;
	}
	catch (RuntimeException ex) {
		this.logger.error("Context initialization failed", ex);
		throw ex;
	}

	if (this.logger.isInfoEnabled()) {
		long elapsedTime = System.currentTimeMillis() - startTime;
		this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " + elapsedTime + " ms");
	}
}

2.3 调用initStrategies()

initStrategies()方法将在DispatcherServlet对应的上下文WebApplicationContext初始化后自动执行,此时Spring上下文中的Bean已经初始化完成,该方法的工作是通过反射机制查找并装配Spring上下文中显示定义的组件Bean,如果找不到就装配默认的组件实例。
// org.springframework.web.servlet.DispatcherServlet
@Override
protected void onRefresh(ApplicationContext context) {
	initStrategies(context);
}

protected void initStrategies(ApplicationContext context) {
	// 初始化上传文件的解析器
	initMultipartResolver(context);
	// 初始化本地化解析器
	initLocaleResolver(context);
	// 初始化主题解析器
	initThemeResolver(context);
	// 初始化处理器器
	initHandlerMappings(context);
	// 初始化处理器适配器
	initHandlerAdapters(context);
	// 初始化处理异常的解析器
	initHandlerExceptionResolvers(context);
	// 初始化请求到视图名的翻译器
	initRequestToViewNameTranslator(context);
	// 初始化视图的解析器
	initViewResolvers(context);
	initFlashMapManager(context);
}
Spring MVC定义了一套默认的组件实现类,即没有显示定义组件Bean,DispatcherServlet就装配默认组件,默认组件配置位置:
// org.springframework.web.servlet.DispatcherServlet.DispatcherServlet.properties
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值