日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringMVC Root WebApplicationContext启动流程

發(fā)布時間:2023/12/15 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringMVC Root WebApplicationContext启动流程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳統(tǒng)的SpringMVC項目中,需要在web.xml中配置Contextlistener。ContextLoaderListener是負責引導啟動和關(guān)閉Spring的Root上下文的監(jiān)聽器。主要將處理委托給ContextLoader和ContextCleanupListener。
類的繼承關(guān)系。

ContextLoaderListener實現(xiàn)了ServletContextListener接口。該接口主要定義了兩個行為:監(jiān)聽上下文創(chuàng)建(contextInitialized)和監(jiān)聽上下文銷毀(contextDestroyed)。
ContextLoaderListener只是將方法的處理委托給ContextLoader。

package org.springframework.web.context;import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener;public class ContextLoaderListener extends ContextLoader implements ServletContextListener {public ContextLoaderListener() {}public ContextLoaderListener(WebApplicationContext context) {super(context);}//初始化Root WebApplication@Overridepublic void contextInitialized(ServletContextEvent event) {//委托給ContextLoaderinitWebApplicationContext(event.getServletContext());}//銷毀Root WebApplication@Overridepublic void contextDestroyed(ServletContextEvent event) { //委托給ContextLoadercloseWebApplicationContext(event.getServletContext());//委托給ContextCleanupListenerContextCleanupListener.cleanupAttributes(event.getServletContext());}}

ContextLoader的initWebApplicationContext方法負責創(chuàng)建root web application context。

//初始化root web application context public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {//校驗是否已經(jīng)存在root application,if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {throw new IllegalStateException("Cannot initialize context because there is already a root application context present - " +"check whether you have multiple ContextLoader* definitions in your web.xml!");}Log logger = LogFactory.getLog(ContextLoader.class);servletContext.log("Initializing Spring root WebApplicationContext");if (logger.isInfoEnabled()) {logger.info("Root WebApplicationContext: initialization started");}long startTime = System.currentTimeMillis();try {// Store context in local instance variable, to guarantee that// it is available on ServletContext shutdown.//創(chuàng)建WebApplicationContext,并保存到變量中,等關(guān)閉時使用if (this.context == null) {this.context = createWebApplicationContext(servletContext);}//如果是ConfigurableWebApplicationContext,則配置上下文并刷新if (this.context instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;if (!cwac.isActive()) {// The context has not yet been refreshed -> provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent ->// determine parent for root web application context, if any.ApplicationContext parent = loadParentContext(servletContext);cwac.setParent(parent);}configureAndRefreshWebApplicationContext(cwac, servletContext);}}//在ServletContext中設(shè)置屬性,表明已經(jīng)配置了root web application contextservletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);ClassLoader ccl = Thread.currentThread().getContextClassLoader();if (ccl == ContextLoader.class.getClassLoader()) {currentContext = this.context;}else if (ccl != null) {currentContextPerThread.put(ccl, this.context);}if (logger.isDebugEnabled()) {logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");}if (logger.isInfoEnabled()) {long elapsedTime = System.currentTimeMillis() - startTime;logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");}return this.context;}catch (RuntimeException ex) {logger.error("Context initialization failed", ex);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);throw ex;}catch (Error err) {logger.error("Context initialization failed", err);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);throw err;}}

該方法主要分為四步:

  • 校驗是否已經(jīng)存在root WebApplicationContext
  • 創(chuàng)建root WebApplicationContext
  • 配置上下文并刷新
  • 綁定root WebApplicationContext到servlet context上
  • 這四步具體分析如下:

    1.校驗

    校驗的過程比較簡單,主要是判斷Servlet Context是否已經(jīng)綁定過WebApplicationContext

    2.創(chuàng)建對象

    createWebApplicationContext()方法負責創(chuàng)建WebApplicationContext對象,主要過程是確定WebApplicationContext類,并實例化:

    protected WebApplicationContext createWebApplicationContext(ServletContext sc) {//查找WebApplicationContext的類Class<?> contextClass = determineContextClass(sc);if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Custom context class [" + contextClass.getName() +"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");}//實例化對象return(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);}

    決定WebApplicationContext類的主要策略是先判斷ServletContext是否配置了contextClass屬性,如果是,則用該屬性指定的類作為WebApplicationContext類,否則則是否默認策略。默認策略是根絕classpath下的ContextLoader.properties中配置的類作為WebApplicatioNCOntext類:

    protected Class<?> determineContextClass(ServletContext servletContext) {//優(yōu)先根據(jù)servletContext配置的contextClass屬性String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);if (contextClassName != null) {try {return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load custom context class [" + contextClassName + "]", ex);}}//在通過classpath下的`ContextLoader.properties`文件制定的類作為WebApplicationContext類//默認是XmlWebApplicationContextelse {contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());try {return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load default context class [" + contextClassName + "]", ex);}}}
    配置與刷新

    創(chuàng)建WebApplicationContext對象后,ContextLoader會判斷是否是ConfigurableWebApplicationContext。
    ConfigurableWebApplicationContext拓展了WebApplicationContext的能力。其不僅擴展了自身方法,還繼承了ConfigurableApplicationContext接口。

    配置與刷新的步驟也正是利用了這些接口提供的能力。

    //配置并刷新上下文protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {//設(shè)置IDif (ObjectUtils.identityToString(wac).equals(wac.getId())) {// The application context id is still set to its original default value// -> assign a more useful id based on available informationString idParam = sc.getInitParameter(CONTEXT_ID_PARAM);if (idParam != null) {wac.setId(idParam);}else {// Generate default id...wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +ObjectUtils.getDisplayString(sc.getContextPath()));}}//WebApplicationContext綁定Servlet Contextwac.setServletContext(sc);String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);if (configLocationParam != null) {wac.setConfigLocation(configLocationParam);}// The wac environment's #initPropertySources will be called in any case when the context// is refreshed; do it eagerly here to ensure servlet property sources are in place for// use in any post-processing or initialization that occurs below prior to #refreshConfigurableEnvironment env = wac.getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(sc, null);}//自定義上下文初始過程,留給用戶的拓展機制customizeContext(sc, wac);//刷新上下文,加載beanwac.refresh();}

    創(chuàng)建流程圖如下:

    轉(zhuǎn)載于:https://www.cnblogs.com/insaneXs/p/11115862.html

    總結(jié)

    以上是生活随笔為你收集整理的SpringMVC Root WebApplicationContext启动流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。