springMVC启动

容器启动,会扫描web.xml文件;扫描到配置的spring的listener时就初始化spring容器;

扫描到DispacthServlet时就初始化该Servlet;初始化Servlet调用init()方法,该方法的实现是在父类HttpServletBean中;继承关系如下:

springMVC启动

@Override
public final void init() throws ServletException {
	if (logger.isDebugEnabled()) {
		logger.debug("Initializing servlet '" + getServletName() + "'");
	}
	// Set bean properties from init parameters.
	try {
	//根据ServletConfig读取配置信息
		PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
		//把DispacthServlet本身传递给工厂类,生成BeanWrapper实例供IoC容器管理
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
		//获取资源加载类
		ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
		bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
		//空实现
		initBeanWrapper(bw);
		//把得到的配置信息给DispacthServlet
		bw.setPropertyValues(pvs, true);
	}
	catch (BeansException ex) {
		logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
		throw ex;
	}
	//继续初始化,由子类实现。具体在FrameworkServlet中
	// Let subclasses do whatever initialization they like.
	initServletBean();
	if (logger.isDebugEnabled()) {
		logger.debug("Servlet '" + getServletName() + "' configured successfully");
	}
}
/**
 * Overridden method of {@link HttpServletBean}, invoked after any bean properties
 *覆盖方法,在配置属性信息后执行;生成DispacthServlet的WebApplicationContext容器;
 * have been set. Creates this servlet's WebApplicationContext.
 */
@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 {
		//这个其实就是根据当前的ServletContext获取spring容器,容器初始化成功后会放入ServletContext中;
		//并标示为WebApplicationContext.ROOT;或者是FrameworkServlet的构造函数中已经传入WebApplicationContext容器;
		//期间调用onRefresh(..)方法,刷新IoC容器;
		//如果是根据ServletContext中得到的容器,则会根据该容器生成新的容器,并把ServletContext中的容器设为父容器;
		//生成的容器类型指定为:XmlWebApplicationContext.class;
		//在刷新容器的同时也会初始化DispacthServlet;
		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");
	}
}
/**
	 *该类在FrameworkServlet内部;由适配的方式调用到该类中的onApplicationEvent
	 * ApplicationListener endpoint that receives events from this servlet's WebApplicationContext
	 * only, delegating to <code>onApplicationEvent</code> on the FrameworkServlet instance.
	 */
	private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {

		public void onApplicationEvent(ContextRefreshedEvent event) {
		//调用外部类FrameworkServlet中的onApplicationEvent方法;
			FrameworkServlet.this.onApplicationEvent(event);
		}
	}
	/**
	 * Callback that receives refresh events from this servlet's WebApplicationContext.
	 * <p>The default implementation calls {@link #onRefresh},
	 * triggering a refresh of this servlet's context-dependent state.
	 * @param event the incoming ApplicationContext event
	 */
	public void onApplicationEvent(ContextRefreshedEvent event) {
		//刷新容器期间,以事件的方式初始化DispatchServlet;
		this.refreshEventReceived = true;//标示
		//这个由DispatchServlet实现
		onRefresh(event.getApplicationContext());
	}
/**
	 * This implementation calls {@link #initStrategies}.
	 */
	@Override
	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);
		//根据org.springframework.web.servlet.HandlerMapping去IoC容器中查找
		//初始化HandlerMappings集合,并待排序
		//可能得到的两个值是RequestMappingHandlerMapping
		//和BeanNameUrlHandlerMapping
		//这两个类中都有一个LinkedHashMap类型的handerMethods属性
		//保存着该类型下的说有映射路径及相关参数,该属性从
		//AbstractHandlerMethodMapping继承而来;
		initHandlerMappings(context);
		//根据org.springframework.web.servlet.HandlerAdapter去IoC容器中查找
		//能得到RequestMappingHandlerAdapter
		//HttpRequestHandlerAdapter
		//SimpleControllerHandlerAdapter
		initHandlerAdapters(context);
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);
		initFlashMapManager(context);
	}

这里又点疑惑:RequestMappingHandlerMapping得到的时候已经有系统中所有的映射路径了,这个是什么时候初始化到该对象中的呢;




你可能感兴趣的:(springMVC启动)