springmvc-源码调试-3-init

HttpServletBean

当用户第一次请求的时候会调用,且只会调用一次

  1. HttpServletBean.init()
  2. FrameworkServlet.initServletBean()
  3. FrameworkServlet.initWebApplicationContext

调用链

  1. HttpServletBean.init()
  2. FrameworkServlet.initServletBean()
  3. FrameworkServlet.initWebApplicationContext()
	protected WebApplicationContext initWebApplicationContext() {
	    // 获取根的Context对象,
        // 比如说我用了Springboot或者注解的方式进行初始化,那么这里的Context就是Spring boot或者其他的context对象
		WebApplicationContext rootContext =
				WebApplicationContextUtils.getWebApplicationContext(getServletContext());
		WebApplicationContext wac = null;
        // 如果 context 不为空
        // 这里的 webApplicationContext 是我们在创建 DispatcherServlet(applicationContext)的时候 设置进来的
		if (this.webApplicationContext != null) {
			wac = this.webApplicationContext;
			// 如果 context 是 ConfigurableWebApplicationContext
			if (wac instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
                // 如果 ConfigurableWebApplicationContext 不是存活状态
                // 这个值由我们设置由 我们传递的 webApplicationContext 在调用刷新的时候 会修改掉
                // 换而言之就是 我们可以不调用 applicationContext.refresh(); 这个方法的话就会进入这个判断
                if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
                    // 父 上下文 ==null
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent -> set
						// the root application context (if any; may be null) as the parent
                        // 设置 父的上下文
						cwac.setParent(rootContext);
					}
                    // 这里会去 调用 refresh()  方法..也就是说 refresh 方法可能在用户第一访问的时候才去刷新...
                    configureAndRefreshWebApplicationContext(cwac);
				}
			}
		}
        // 如果为空,也就说我们在创建 DispatcherServlet()的时候 没有传递 applicationContext 则会进入 这个判断
		if (wac == null) {
            // 查看是否有已在servlet上下文中注册。 如果有一个存在,就假定它存在父上下文(如果有)已经设置,并且用户已执行任何初始化,如:设置上下文id
            // 会根据 contextAttribute 去查找 WebApplicationContext
            wac = findWebApplicationContext();
		}
		//如果没有找到那么就通过rootContext 去创建一个Context对象
		if (wac == null) {
			// 需要注意的是这里去创建的是 XmlWebApplicationContext
            // 需要 /WEB-INF/app-servlet.xml 因为去加载 Bean 的是会读取这个 文件...
            // 而由于我使用的注解类型所以不适用自动创建...
			wac = createWebApplicationContext(rootContext);
		}
        // 判断 是否刷新过
		if (!this.refreshEventReceived) {
			//上下文不是具有refreshsupport的ConfigurableApplicationContext,或者在构造时注入的上下文已经被刷新->在此处手动触发初始onRefresh。
			synchronized (this.onRefreshMonitor) {
				onRefresh(wac);
			}
		}
        //如果允许公开Context的话那么就把spring context放入到spring的ServletContext中
        // 这样我们就可以通过 Servlet域 获取到 这个 WebApplicationContext
		if (this.publishContext) {
			// Publish the context as a servlet context attribute.
			String attrName = getServletContextAttributeName();
			getServletContext().setAttribute(attrName, wac);
		}

		return wac;
	}

onRefresh

这个方法比较重要…

FrameworkServlet.onRefresh() 定义的空实现,由DispatcherServlet.onRefresh() 覆盖了.所以这里调用的是 DispatcherServlet.onRefresh()

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

initStrategies

DispatcherServlet.initStrategies()就是初始化一些对象,当然如果从 容器中获取到就不会进行初始化,如果没有获取到才会创建一个默认的

DispatcherServlet.properties 默认的文件 ,会从这个文件读出来…然后创建默认值

protected void initStrategies(ApplicationContext context) {
	    // 初始化 MultipartResolver 如果没有 则会设置一个 null
        // 用于处理文件上传
		initMultipartResolver(context);
		//  初始化 LocaleResolver 如果没有 则会创建一个默认的
		initLocaleResolver(context);
		// 初始化 ThemeResolver 如果没有 则会创建一个默认的
		initThemeResolver(context);
		// 初始化 HadnlerMappings
		initHandlerMappings(context);
		// 初始化 HandlerAdapters
		initHandlerAdapters(context);
		// 初始化 HandlerExceptionResolvers
		initHandlerExceptionResolvers(context);
        // 初始化 RequestToViewNameTranslator
        initRequestToViewNameTranslator(context);
        // 初始化 ViewResolvers
        initViewResolvers(context);
        // 初始化 FlashMapManager
        initFlashMapManager(context);
	}

后言

剩下的initStrategies 参考后续文章… 会一个章节章节的分析里面的代码
本来想一起 分析的.但是合在一起 太长太长了.如果每个点都讲清楚… 太乱太乱了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值