Spring深度解析-19、DispatcherServlet的初始化

本文深入探讨了Spring的DispatcherServlet初始化过程,解释了其在ContextLoaderListener完成根上下文初始化后的启动时机,特别是load-on-startup配置的影响。内容涉及HttpServletBean的init方法、DispatcherServlet的initServletBean方法,以及如何设置上下文和初始化Spring MVC所需的bean。

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

昨天讲到DispatcherServlet因为继承了FrameworkServlet、HttpServletBean、HttpServlet,因此可以通过Servlet的API对请求进行一些处理与响应。
DispatcherServlet的初始化在ContextLoaderListener完成对根上下文的初始化之后才会执行。
具体的初始化时间取决于web.xml中servlet关于load-on-startup的配置。
当load-on-startup为负数或者没有配置时,在第一次request请求时加载;
当load-on-startup不为负数时,代表DispatcherServlet在ContextLoaderListener完成根上下文的初始化之后即加载。
下面来看DispatcherServlet具体的初始化源码:
HttpServletBean重写了其父类HttpServlet的init方法:

public final void init() throws ServletException {

		// Set bean properties from init parameters.
		PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
		if (!pvs.isEmpty()) {
			try {
				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) {
				if (logger.isErrorEnabled()) {
					logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
				}
				throw ex;
			}
		}

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

HttpServletBean的init方法,读取Servlet的初始化参数,然后调用initServletBean来初始化Servlet的Bean对象。
这个initServletBean是一个钩子方法,由子类去实现。
在这里调用到子类

protected final void initServletBean() throws ServletException {
		getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
		if (logger.isInfoEnabled()) {
			logger.info("Initializing Servlet '" + getServletName() + "'");
		}
		long startTime = System.currentTimeMillis();

		try {
			this.webApplicationContext = initWebApplicationContext();
			initFrameworkServlet();
		}
		catch (ServletException | RuntimeException ex) {
			logger.error("Context initialization failed", ex);
			throw ex;
		}

		if (logger.isDebugEnabled()) {
			String value = this.enableLoggingRequestDetails ?
					"shown which may lead to unsafe logging of potentially sensitive data" :
					"masked to prevent unsafe logging of potentially sensitive data";
			logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +
					"': request parameters and headers will be " + value);
		}

		if (logger.isInfoEnabled()) {
			logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
		}
	}

initServletBean中实现了DispatcherServlet中上下文的实现,设置上下文的根上下文,并使ServletContext持有这个DispatcherServlet上下文。
initWebApplicationContext中的onRefresh()方式用来在初始化spring mvc需要的bean

protected void onRefresh(ApplicationContext context) {
		initStrategies(context);
	}

	/**
	 * Initialize the strategy objects that this servlet uses.
	 * <p>May be overridden in subclasses in order to initialize further strategy objects.
	 */
	protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);
		initLocaleResolver(context);
		initThemeResolver(context);
		//这里配置path 与 handler ,也是什么请求,走什么样的处理器
		//而处理器,是一系列拦截器+Controller组成
		initHandlerMappings(context);
		initHandlerAdapters(context);
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);
		initFlashMapManager(context);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值