在initWebApplicationContext方法是用来创建容器的,核心代码如下: 今天主要来看configureAndRefreshWebApplicationContext方法中最后的wac.refresh
= null) { wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + } wac.setParent(parent); wac.setServletContext(sc); //设置spring的配置文件 wac.setConfigLocation (sc.getInitParameter(CONFIG_LOCATION_PARAM)); customizeContext(sc, wac); //spring容器初始化 wac.refresh(); return wac; } ContextLoaderListener构建Root Context时序图: protected WebApplicationContext onRefresh(wac); } if (this.publishContext) { // Publish the context as a
(wac); return wac; } configureAndRefreshWebApplicationContext() protected void configureAndRefreshWebApplicationContext (ConfigurableWebApplicationContext wac){ if(ObjectUtils.identityToString(wac).equals(wac.getId =null){ wac.setId(this.contextId); } else{ //根据可用信息分配更有用的ID wac.setId (getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace ); applyInitializers(wac); //初始化springMVC各种的相关配置,各种注入的Controller,配置文件等 wac.refresh
//这里,ioc容器已经创建初始化完成,执行onRefresh(wac)进一步初始化MVC其他模块,后面说明 onRefresh(wac); } if (getEnvironment()); wac.setParent(parent); wac.setConfigLocation(getContextConfigLocation (ConfigurableWebApplicationContext wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId ()); wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener() ); applyInitializers(wac); //嗲用容器的refresh()方法,完成日期初始化 wac.refresh();
== null) { wac = findWebApplicationContext(); } //给上一步创建好的IoC容器赋值 if (wac == null) { wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { if (this.contextId ! (getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace( )); wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener())); ); applyInitializers(wac); wac.refresh(); } 从上面的代码可以看出,在configAndRefreshWebApplicationContext(
== null) { wac = findWebApplicationContext(); } //给上一步创建好的IoC容器赋值 if (wac == null) { wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { if (this.contextId ! (getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace( )); wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener())); ); applyInitializers(wac); wac.refresh(); } 从上面的代码可以看出,在configAndRefreshWebApplicationContext()
(wac); return wac; } protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // The application (getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace (wac, new ContextRefreshListener())); // The wac environment's #initPropertySources will be ); applyInitializers(wac); wac.refresh(); } 将WebApplicationContext设置到ServletContext
(getEnvironment()); wac.setParent(parent); wac.setConfigLocation(getContextConfigLocation()); // 配置并刷新容器 configureAndRefreshWebApplicationContext(wac); return wac; } protected void (wac).equals(wac.getId())) { // 设置容器 id if (this.contextId ! ()); wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener())); postProcessWebApplicationContext(wac); applyInitializers(wac); // 刷新容器 wac.refresh(); } 以上就是创建
cwac = (ConfigurableWebApplicationContext) wac; if (! has performed any initialization such as setting the context id //如果当前Servlet不存在一个子IoC容器则去查找一下 wac = findWebApplicationContext(); } if (wac == null) { // No context instance is defined for (getEnvironment()); wac.setParent(parent); wac.setConfigLocation(getContextConfigLocation()); configureAndRefreshWebApplicationContext(wac); return wac; } 该方法用于创建一个子IoC容器并将根IoC容器做为其父容器,接着进行配置和刷新操作用于构造相关的
= null) { //上下文实例在构造时被注入->使用它 wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext = findWebApplicationContext(); } if (wac == null) { //创建WebApplicationContext wac = createWebApplicationContext (wac); return wac; } 配置刷新容器 protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { if (this.contextId ! ); //主要是为了在调用refresh方法之前做一些准备工作 applyInitializers(wac); //主动调用refresh方法,触发上面刚添加的监听器 wac.refresh()
... } protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac customizeContext(sc, wac); wac.refresh(); ... } // 由此可见所有的ApplicationContextInitializer的执行,都发生在 wac.refresh();之前 protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext ConfigurableApplicationContext> initializer : this.contextInitializers) { initializer.initialize(wac postProcessWebApplicationContext(wac); applyInitializers(wac); wac.refresh(); } protected void
) wac; if (! the parent cwac.setParent(rootContext); } configureAndRefreshWebApplicationContext(cwac); } } } if (wac -> create a local one // 创建WebApplicationContext wac = createWebApplicationContext(rootContext); } if = null) { wac.setConfigLocation(configLocation); } configureAndRefreshWebApplicationContext(wac); return wac; } ③DispatcherServlet初始化策略 FrameworkServlet创建WebApplicationContext后,刷新容器,调用onRefresh(wac),此方法在DispatcherServlet
== null) { wac = findWebApplicationContext(); } if (wac == null) { wac = createWebApplicationContext (ConfigurableWebApplicationContext wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId()) (getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace()) (wac, new ContextRefreshListener())); // 同之前~ ConfigurableEnvironment env = wac.getEnvironment() 备注:用到了这个常量ContextLoader.GLOBAL_INITIALIZER_CLASSES_PARAM applyInitializers(wac); wac.refresh();
: this.webApplicationContext = initWebApplicationContext(); initFrameworkServlet(); 跟进第一段代码,由于第一次启动,wac (getEnvironment()); wac.setParent(parent); wac.setConfigLocation(getContextConfigLocation()); configureAndRefreshWebApplicationContext ()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace()); wac.addApplicationListener (new SourceFilteringListener(wac, new ContextRefreshListener())); // The wac environment's #initPropertySources ); applyInitializers(wac); wac.refresh(); 最后一句 wac.refresh()代码,跟进去发现调用的是 org.springframework.context.support.AbstractApplicationContext
== null) wac = findWebApplicationContext(); /** 步骤3:如果wac还是找不到,则创建一个wac */ if (wac == null ) { /** 步骤1:准备工作——初始化wac */ if (ObjectUtils.identityToString(wac).equals(wac.getId())) { ()); wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener())); ); // 空方法,留给子类去覆盖实现想· applyInitializers(wac); /** 步骤2:调用wac的refresh()方法进行IOC初始化 */ wac.refresh ; return wac; } 1.2.3> 如果wac还是找不到,那就创建一个wac 如果通过上面的努力,我们依然没有获得Web应用上下文,那我们就只好通过createWebApplicationContext
sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { String idParam = null) { wac.setId(idParam); }else { wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX = null) { wac.setConfigLocation(configLocationParam); } ConfigurableEnvironment ) env).initPropertySources(sc, null); } customizeContext(sc, wac); wac.refresh 关注configureAndRefreshWebApplicationContext方法的最后一行代码wac.refresh(),是不是有点眼熟,继续跟踪代码,refresh方法的具体代码如下。
WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContext wac cwac =(ConfigurableWebApplicationContext) wac; if (! the // user has performed any initialization such as setting the context id wac = findWebApplicationContext(); } if (wac == null) { // No context instance is defined (wac); return wac; } ③DispatcherServlet初始化策略 FrameworkServlet创建WebApplicationContext后,刷新容器,调用onRefresh
ConfigurableWebApplicationContext.class.getName() + "]"); } ConfigurableWebApplicationContext wac String contextPath = (String) ServletContext.class.getMethod("getContextPath").invoke(sc); wac.setId IllegalStateException("Failed to invoke Servlet 2.5 getContextPath method", ex); } } wac.setParent (parent); wac.setServletContext(sc); wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM )); customizeContext(sc, wac); wac.refresh(); return wac; } 关闭上下文代码 //关闭指定Servlet上下文中的
WebApplicationContext wac = findWebApplicationContext(); if (wac ! = null) { this.delegate = initDelegate(wac); } } } } @Override public void doFilter = findWebApplicationContext(); if (wac == null) { throw new IllegalStateException("No WebApplicationContext ; } delegateToUse = initDelegate(wac); } this.delegate = delegateToUse; } } ; } delegateToUse = initDelegate(wac); } this.delegate = delegateToUse; } }
== null) { wac = findWebApplicationContext(); } if (wac == null) { wac = createWebApplicationContext 这三套组合拳下来,wac 肯定是有值了。 最后将 wac 保存到到 ServletContext 中。 wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // The application context id ()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace()); wac.addApplicationListener