麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Spring4.3.x 容器在web應(yīng)用中的初始化過程

2019-11-10 20:16:00
字體:
供稿:網(wǎng)友

概述

SPRing在web應(yīng)用中的默認(rèn)容器類為xmlWebapplicationContext,這個(gè)容器類通過xml文件獲取所有的配置信息。它的繼承結(jié)構(gòu)如下圖,(點(diǎn)此查看大圖) XmlWebApplicationContext繼承結(jié)構(gòu)

在web應(yīng)用中,不管是ContextLoaderListener,還是DispatcherServlet初始化的時(shí)候,都是以XmlWebApplicationContext為默認(rèn)容器。在下面的研究中,我將以ContextLoaderListener的初始化過程介紹spring容器在web應(yīng)用的初始化。

ContextLoaderListener的初始化過程中最主要的任務(wù)時(shí)加載spring容器,并把此容器加入到ServletContext中作為整個(gè)web應(yīng)用的跟容器。ContextLoaderListener加載spring容器大致分為兩個(gè)階段,第一個(gè)階段是解析web.xml文件中的初始化參數(shù)以對spring容器做定制化操作,簡單的說就是定制spring容器;第二階段是spring容器的刷新過程。下面分別對這兩個(gè)階段進(jìn)行探討。

第一階段 定制spring容器

ContextLoaderListener實(shí)現(xiàn)了ServletContextListener,因此web容器啟動(dòng)的時(shí)候就會(huì)執(zhí)行它的contextInitialized方法,此方法的代碼如下。

public void contextInitialized(ServletContextEvent event) { // 獲取ContextLoader對象 this.contextLoader = createContextLoader(); if (this.contextLoader == null) { this.contextLoader = this; } this.contextLoader.initWebApplicationContext(event.getServletContext()); } @Override public void contextInitialized(ServletContextEvent event) { // 執(zhí)行父類ContextLoader的initWebApplicationContext方法 initWebApplicationContext(event.getServletContext()); }

這段代碼主要是調(diào)用父類ContextLoader的initWebApplicationContext(ServletContext servletContext)方法,下面是initWebApplicationContext方法在ContextLoader類中的代碼。

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { // 檢查ServletContext是否已經(jīng)有了根容器 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 { if (this.context == null) { // 創(chuàng)建容器,據(jù)contextClass初始化參數(shù)指定或者使用默認(rèn)的XmlWebApplicationContext類 this.context = createWebApplicationContext(servletContext); } if (this.context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; if (!cwac.isActive()) { // 如果容器沒有被刷新,執(zhí)行以下操作 // 設(shè)置父容器 if (cwac.getParent() == null) { // 加載父容器。 // 通過locatorFactorySelector上下文初始化參數(shù)指定父容器所在的配置文件路徑 // 通過parentContextKey上下文初始化參數(shù)指定父容器的名稱 ApplicationContext parent = loadParentContext(servletContext); cwac.setParent(parent); } // 配置并執(zhí)行容器刷新操作 configureAndRefreshWebApplicationContext(cwac, servletContext); } } // 把spring容器加入到ServletContext中作為根容器 servletContext.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; } }

這段代碼分成4步,首先通過調(diào)用ContextLoader的createWebApplicationContext(ServletContext sc)方法來創(chuàng)建spring容器,然后設(shè)置spring容器的父容器,接著調(diào)用ContextLoader的configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc)方法來配置并刷新spring容器,最后把容器保存到servlet容器中。最后一步的代碼已經(jīng)在上面體現(xiàn)了,下面我們來解析前三步的代碼。

1. 創(chuàng)建spring容器。

調(diào)用ContextLoader的createWebApplicationContext(ServletContext sc)方法,這個(gè)方法的代碼如下。

protected WebApplicationContext createWebApplicationContext(ServletContext sc) { // 獲取容器類對象 Class<?> contextClass = determineContextClass(sc); if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]"); } // 使用容器類對象來實(shí)例化容器 return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); }

上面主要是通過ContextLoader的determineContextClass(ServletContext servletContext)方法獲取容器類對象,然后實(shí)例化容器。下面是determineContextClass方法的代碼。

/** * 獲取容器類對象 **/ protected Class<?> determineContextClass(ServletContext servletContext) { // 聲明:public static final String CONTEXT_CLASS_PARAM = "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); } } else { 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); } } }

determineContextClass從ServletContext對象中獲取contextClass初始化參數(shù)的值,如果這個(gè)參數(shù)有值,則使用這個(gè)參數(shù)指定的容器類,否則使用默認(rèn)的容器類XmlWebApplicationContext。如果不使用spring的默認(rèn)容器,可以在web.xml中通過配置contextClass指定其他容器類,比如。

<!-- 定義contextClass參數(shù) --> <context-param> <param-name>contextClass</param-name> <param-value> com.chyohn.context.XmlWebApplicationContext </param-value> </context-param>

2. 指定父容器。

創(chuàng)建完spring容器后,initWebApplicationContext中會(huì)調(diào)用ContextLoader的 loadParentContext(ServletContext servletContext)方法來獲取父容器,并把這個(gè)父容器與剛創(chuàng)建的容器關(guān)聯(lián)上。loadParentContext方法的代碼如下。

protected ApplicationContext loadParentContext(ServletContext servletContext) { ApplicationContext parentContext = null; // 聲明:public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector"; String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM); // 聲明:public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey"; String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM); if (parentContextKey != null) { // locatorFactorySelector可能會(huì)為null, 則會(huì)使用默認(rèn)的 "classpath*:beanRefContext.xml" BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); Log logger = LogFactory.getLog(ContextLoader.class); if (logger.isDebugEnabled()) { logger.debug("Getting parent context definition: using parent context key of '" + parentContextKey + "' with BeanFactoryLocator"); } this.parentContextRef = locator.useBeanFactory(parentContextKey); parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } return parentContext; }

這里通過ServletContext 獲取初始化參數(shù)locatorFactorySelector指定的定義父容器的xml文件的地址,同時(shí)獲取初始化參數(shù)parentContextKey指定的父容器在前面xml文件中設(shè)置的bean名稱。下面是一個(gè)列子。

第一步在classes路徑下創(chuàng)建名為parentBeanRefContext.xml的xml文件(名稱可以隨便取),我這里的內(nèi)容如下。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 指定容器 --> <bean id="parentContext" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>parentOfRootContext.xml</value> </list> </constructor-arg> </bean></beans>

其中parentOfRootContext.xml文件為一個(gè)普通的spring配置文件,這里就不舉例了。

第二步,在web.xml文件中做如下配置。

<!-- 定義locatorFactorySelector參數(shù) --> <context-param> <param-name>locatorFactorySelector</param-name> <param-value> classpath:parentBeanRefContext.xml </param-value> </context-param> <!-- 定義parentContextKey參數(shù) --> <context-param> <param-name>parentContextKey</param-name> <param-value>parentContext</param-value> </context-param>

這樣就向容器中指定了一個(gè)父容器。在這里如果在第一步中創(chuàng)建的xml文件的名稱為beanRefContext.xml,那么在web.xml文件中就不用配置locatorFactorySelector參數(shù)。

3. 配置并刷新spring容器

設(shè)置了父容器后,執(zhí)行ContextLoader的configureAndRefreshWebApplicationContext方法,在容器刷新前對容器進(jìn)行初始化配置,代碼如下

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // 為容器設(shè)置一個(gè)有用的ID // 聲明:public static final String CONTEXT_ID_PARAM = "contextId"; String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); } else { // 生成一個(gè)默認(rèn)ID if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) { // servlet 2.5以前的版本 wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getServletContextName())); } else { // servlet 2.5及其以上的版本wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } } // 把ServletContext保存到容器中 wac.setServletContext(sc); // 設(shè)置容器要加載的配置文件所在的路徑 // 通過contextConfigLocation上下文參數(shù)指定配置文件路徑 // 聲明:public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation"; String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (initParameter != null) { wac.setConfigLocation(initParameter); } // 在容器刷新前,自定義容器。 // 執(zhí)行用戶通過contextInitializerClasses上下文參數(shù)指定的容器初始化器 customizeContext(sc, wac); // 刷新容器 wac.refresh(); } protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // 為容器設(shè)置一個(gè)有用的ID // 聲明:public static final String CONTEXT_ID_PARAM = "contextId"; String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); } else { // 創(chuàng)建一個(gè)默認(rèn)的id wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } // 把ServletContext保存到容器中 wac.setServletContext(sc); // 設(shè)置容器要加載的配置文件所在的路徑 // 通過contextConfigLocation上下文參數(shù)指定配置文件路徑 // 聲明:public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation"; String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocationParam != null) { wac.setConfigLocation(configLocationParam); } // 提前執(zhí)行容器環(huán)境對象的initPropertySources方法,以確保servlet屬性資源可應(yīng)用于容器刷新前的任何初始化操作。 ConfigurableEnvironment env = wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); } // 在容器刷新前,自定義容器。 // 執(zhí)行用戶通過contextInitializerClasses上下文參數(shù)指定的容器初始化器 customizeContext(sc, wac); // 刷新容器 wac.refresh(); }

這段代碼處理配置在web.xml中的2個(gè)初始化參數(shù),第一個(gè)是用于標(biāo)志容器id的contextId初始化參數(shù),第二是用于指定配置文件地址的contextConfigLocation初始化參數(shù)。對于contextId參數(shù)沒有過多的探討,至于contextConfigLocation參數(shù),可以配置,也可以不配置。如果需要通過contextConfigLocation參數(shù)指定多個(gè)配置文件,配置文件地址之間可以通過英文逗號(hào)、分號(hào)、空格、制表符、換行符隔開。如果沒有配置contextConfigLocation參數(shù),XmlWebApplicationContext將使用WEB-INF目錄下的默認(rèn)配置文件地址,代碼如下。

/** Default config location for the root context */ public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; /** Default prefix for building a config location for a namespace */ public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; /** Default suffix for building a config location for a namespace */ public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; @Override protected String[] getDefaultConfigLocations() { if (getNamespace() != null) { return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; } else { // 返回配置地址/WEB-INF/applicationContext.xml return new String[] {DEFAULT_CONFIG_LOCATION}; } }

根據(jù)這段代碼,可以獲得兩個(gè)信息。 其一:如果spring容器有命名空間,則開發(fā)者可以在WEB-INF目錄下創(chuàng)建以命名空間為名稱的xml配置文件。 其二:如果spring容器沒有命名空間,則開發(fā)者可以在WEB-INF目錄下創(chuàng)建以applicationContext為名稱的xml配置文件。

在configureAndRefreshWebApplicationContext方法中還調(diào)用ContextLoader的customizeContext方法來執(zhí)行用戶指定ApplicationContextInitializer對象,下面是customizeContext方法的代碼。

protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) { // 獲取ApplicationContextInitializer類對象列表 List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses = determineContextInitializerClasses(servletContext); if (initializerClasses.size() == 0) { // 沒有指定任何 ApplicationContextInitializers對象,則什么都不做,直接返回 return; } Class<?> contextClass = applicationContext.getClass(); ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances = new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>(); for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) { // 從initializerClass對象獲取ApplicationContextInitializer的泛型類對象 Class<?> initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class); // 檢查contextClass是否是initializerContextClass類對象指定的類的實(shí)現(xiàn) Assert.isAssignable(initializerContextClass, contextClass, String.format( "Could not add context initializer [%s] as its generic parameter [%s] " + "is not assignable from the type of application context used by this " + "context loader [%s]: ", initializerClass.getName(), initializerContextClass.getName(), contextClass.getName())); initializerInstances.add(BeanUtils.instantiateClass(initializerClass)); } ConfigurableEnvironment env = applicationContext.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { // 初始化Property資源 ((ConfigurableWebEnvironment)env).initPropertySources(servletContext, null); } // 一個(gè)一個(gè)的執(zhí)行ApplicationContextInitializer對象 Collections.sort(initializerInstances, new AnnotationAwareOrderComparator()); for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) { initializer.initialize(applicationContext); } }

這段代碼主要是調(diào)用ContextLoader對象的determineContextInitializerClasses方法來獲取ApplicationContextInitializer類對象列表,并使用每個(gè)ApplicationContextInitializer對象來對spring容器做更多的初始化操作。下面是determineContextInitializerClasses的代碼。

protected List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> determineContextInitializerClasses(ServletContext servletContext) { List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> classes = new ArrayList<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>(); // 從ServletContext中獲取應(yīng)用于所有spring web應(yīng)用容器的ApplicationContextInitializer實(shí)現(xiàn)類全名稱 // 聲明有:public static final String GLOBAL_INITIALIZER_CLASSES_PARAM = "globalInitializerClasses"; String globalClassNames = servletContext.getInitParameter(GLOBAL_INITIALIZER_CLASSES_PARAM); if (globalClassNames != null) { for (String className : StringUtils.tokenizeToStringArray(globalClassNames, INIT_PARAM_DELIMITERS)) { classes.add(loadInitializerClass(className)); } } // 從ServletContext中獲取專為為此容器指定的ApplicationContextInitializer實(shí)現(xiàn)類全名稱 // 聲明:public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses"; String localClassNames = servletContext.getInitParameter(CONTEXT_INITIALIZER_CLASSES_PARAM); if (localClassNames != null) { for (String className : StringUtils.tokenizeToStringArray(localClassNames, INIT_PARAM_DELIMITERS)) { classes.add(loadInitializerClass(className)); } } return classes; } private Class<ApplicationContextInitializer<ConfigurableApplicationContext>> loadInitializerClass(String className) { try { Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); Assert.isAssignable(ApplicationContextInitializer.class, clazz); return (Class<ApplicationContextInitializer<ConfigurableApplicationContext>>) clazz; } catch (ClassNotFoundException ex) { throw new ApplicationContextException("Failed to load context initializer class [" + className + "]", ex); } }

determineContextInitializerClasses方法從ServletContext中獲取初始化參數(shù)contextInitializerClasses和globalInitializerClasses的值,這個(gè)值指定了用戶自定義的ApplicationContextInitializer實(shí)現(xiàn)類全名稱。然后根據(jù)類的全名稱創(chuàng)建Class對象。其中如果需要指定多個(gè)ApplicationContextInitializer實(shí)現(xiàn)類,那么實(shí)現(xiàn)類的全名稱之間使用英文逗號(hào)隔開,比如下面的配置。

<!-- 定義globalInitializerClasses參數(shù) --> <context-param> <param-name>globalInitializerClasses</param-name> <param-value> com.damuzee.web.app.GlobalApplicationContextInitializer1, com.damuzee.web.app.GlobalApplicationContextInitializer2, com.damuzee.web.app.GlobalApplicationContextInitializer3 </param-value> </context-param> <!-- 定義contextInitializerClasses參數(shù) --> <context-param> <param-name>contextInitializerClasses</param-name> <param-value> com.damuzee.web.app.XmlApplicationContextInitializer1, com.damuzee.web.app.XmlApplicationContextInitializer2, com.damuzee.web.app.XmlApplicationContextInitializer3 </param-value> </context-param>

到此,在web應(yīng)用中spring容器初始化的第一個(gè)階段就完成了。configureAndRefreshWebApplicationContext方法通過調(diào)用容器的refresh()方法進(jìn)入容器初始化的第二階段——容器的刷新過程

第二階段: 容器的刷新過程

關(guān)于spring容器的刷新過程已經(jīng)在另一篇文章中描述了,詳見 Spring ApplicationContext的刷新過程

總結(jié)

在spring容器初始化的第一個(gè)階段,我們可以通過web.xml文件的配置來定制spring容器。通過web.xml文件,我們可以指定其他容器類、父容器、容器的id、需要加載的配置文件地址、以及自定義容器初始化器ApplicationContextInitializer對象。具體例子如下。

通過設(shè)置contextClass參數(shù)指定容器,例如 <context-param> <param-name>contextClass</param-name> <param-value> com.chyohn.context.XmlWebApplicationContext </param-value> </context-param>設(shè)置locatorFactorySelector和parentContextKey參數(shù)指定父容器,例如 <!-- 定義locatorFactorySelector參數(shù) --> <context-param> <param-name>locatorFactorySelector</param-name> <param-value> classpath:parentBeanRefContext.xml </param-value> </context-param> <!-- 定義parentContextKey參數(shù) --> <context-param> <param-name>parentContextKey</param-name> <param-value>parentContext</param-value> </context-param>

上面的parentBeanRefContext.xml配置如下

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 指定容器 --> <bean id="parentContext" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>parentOfRootContext.xml</value> </list> </constructor-arg> </bean></beans> 設(shè)置contextId參數(shù)指定容器的Id,配置如下。 <context-param> <param-name>contextId</param-name> <param-value>myContextId</param-value> </context-param>設(shè)置contextConfigLocation參數(shù)指定加載的配置文件地址,配置如下。 <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:webApplicationContent.xml classpath:application-service.xml </param-value> </context-param>設(shè)置contextInitializerClasses參數(shù)指定容器初始化器,該初始化器將在容器刷新前執(zhí)行,如果有多個(gè)初始化器,使用英文逗號(hào)“,”隔開,例如 <!-- 定義contextInitializerClasses參數(shù) --> <context-param> <param-name>contextInitializerClasses</param-name> <param-value> com.damuzee.web.app.XmlApplicationContextInitializer1, com.damuzee.web.app.XmlApplicationContextInitializer2, com.damuzee.web.app.XmlApplicationContextInitializer3 </param-value> </context-param>設(shè)置globalInitializerClasses參數(shù)指定所有容器公共的初始化器,該初始化器將在容器刷新前執(zhí)行,如果有多個(gè)初始化器,使用英文逗號(hào)“,”隔開,例如 <!-- 定義globalInitializerClasses參數(shù) --> <context-param> <param-name>globalInitializerClasses</param-name> <param-value> com.damuzee.web.app.GlobalApplicationContextInitializer1, com.damuzee.web.app.GlobalApplicationContextInitializer2, com.damuzee.web.app.GlobalApplicationContextInitializer3 </param-value> </context-param>

有了ApplicationContextInitializer對象,可以對容器的初始化做更多操作,比如設(shè)置容器id、設(shè)置父容器、設(shè)置加載的配置文件地址、添加容器級的bean工廠后處理器、監(jiān)聽器等等。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美一级一区二区三区 | 污黄视频在线观看 | 欧美成人一区免费视频 | 黄色18网站 | 久久99网 | 婷婷久久久久久 | h视频免费观看 | 精品久久一区二区三区 | 电影av在线| 日本在线视频二区 | 得得啪在线 | 日韩剧情片 | 精品一区二区久久久久 | 久久国产成人午夜av浪潮 | 老子午夜影院 | 亚洲极色| 日韩视频www| 毛片网站网址 | 欧洲成人在线视频 | 2023av在线视频 | 久久精品视频一区 | 久久一区国产 | 久久黄色影院 | 色av成人天堂桃色av | 中文字幕亚洲情99在线 | 久久国产成人精品国产成人亚洲 | 日韩视频一区在线 | 亚洲一区二区三区精品在线观看 | 国产精品视频久 | 黄色大片在线免费观看 | 久久草在线视频免费 | 亚洲乱码精品久久久久 | 欧美性生活视频免费 | av在线免费看网址 | 黄色影院一级片 | 欧美一级黄色免费 | 激情网站免费观看 | 亚洲精品在线观看免费 | 黄色网址进入 | 欧美成人精品一区二区 | 欧美成人做爰高潮片免费视频 |