国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

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

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

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

概述

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

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

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

第一階段 定制spring容器

ContextLoaderListener實現(xiàn)了ServletContextListener,因此web容器啟動的時候就會執(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)方法,這個方法的代碼如下。

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() + "]"); } // 使用容器類對象來實例化容器 return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); }

上面主要是通過ContextLoader的determineContextClass(ServletContext servletContext)方法獲取容器類對象,然后實例化容器。下面是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ù)的值,如果這個參數(shù)有值,則使用這個參數(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中會調(diào)用ContextLoader的 loadParentContext(ServletContext servletContext)方法來獲取父容器,并把這個父容器與剛創(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可能會為null, 則會使用默認(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ù)parentContextKey指定的父容器在前面xml文件中設(shè)置的bean名稱。下面是一個列子。

第一步在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文件為一個普通的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>

這樣就向容器中指定了一個父容器。在這里如果在第一步中創(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è)置一個有用的ID // 聲明:public static final String CONTEXT_ID_PARAM = "contextId"; String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); } else { // 生成一個默認(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è)置一個有用的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)建一個默認(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個初始化參數(shù),第一個是用于標(biāo)志容器id的contextId初始化參數(shù),第二是用于指定配置文件地址的contextConfigLocation初始化參數(shù)。對于contextId參數(shù)沒有過多的探討,至于contextConfigLocation參數(shù),可以配置,也可以不配置。如果需要通過contextConfigLocation參數(shù)指定多個配置文件,配置文件地址之間可以通過英文逗號、分號、空格、制表符、換行符隔開。如果沒有配置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ù)這段代碼,可以獲得兩個信息。 其一:如果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類對象指定的類的實現(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); } // 一個一個的執(zhí)行ApplicationContextInitializer對象 Collections.sort(initializerInstances, new AnnotationAwareOrderComparator()); for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) { initializer.initialize(applicationContext); } }

這段代碼主要是調(diào)用ContextLoader對象的determineContextInitializerClasses方法來獲取ApplicationContextInitializer類對象列表,并使用每個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實現(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實現(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的值,這個值指定了用戶自定義的ApplicationContextInitializer實現(xiàn)類全名稱。然后根據(jù)類的全名稱創(chuàng)建Class對象。其中如果需要指定多個ApplicationContextInitializer實現(xiàn)類,那么實現(xiàn)類的全名稱之間使用英文逗號隔開,比如下面的配置。

<!-- 定義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容器初始化的第一個階段就完成了。configureAndRefreshWebApplicationContext方法通過調(diào)用容器的refresh()方法進(jìn)入容器初始化的第二階段——容器的刷新過程

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

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

總結(jié)

在spring容器初始化的第一個階段,我們可以通過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í)行,如果有多個初始化器,使用英文逗號“,”隔開,例如 <!-- 定義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í)行,如果有多個初始化器,使用英文逗號“,”隔開,例如 <!-- 定義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ā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
天天干天天摸| а√资源新版在线天堂| 亚洲精品自拍区在线观看| 另类视频在线| 天堂在线免费av| 中文字幕第一页av| 国产色在线观看| 亚洲精品国自产拍在线观看| 亚洲一区二区三区在线观看网站| 99久久国产视频| а√最新版地址在线天堂| 欧美午夜电影一区二区三区| 久草电影在线| 中文字幕久热在线精品| 国产视频xxxx| 午夜羞羞小视频在线观看| 免费日本黄色| 97中文字幕| 开心激情五月婷婷| 精品亚洲成a人片在线观看| 久久久久久91精品色婷婷| 在线成人综合色一区| 自拍av在线| 日本调教视频在线观看| 天堂资源在线中文| eeuss影院网站免费观看| 国产高清视频免费最新在线| 日本成人a视频| 国产丝袜在线播放| 九九热在线视频免费观看| 亚洲91av| 精品极品三级久久久久| 国产毛片毛片| 在线免费观看黄色av| 国产天堂资源| 国产香蕉尹人视频在线| 青草视频在线播放| 亚洲精品一区中文字幕电影| 国产高清一级片| 国产精品被窝福利一区| 最新中文字幕av专区| 人日人天天爽| 亚洲综合天堂网| 性网站在线看| 欧美另类在线视频| 欧美日韩在线中文字幕| jizz亚洲大全| 欧美日韩在线视频免费观看| 在线视频中文字幕第一页| 国产夫妻视频| 在线播放黄色网址| av在线日韩国产精品| 亚洲日本伊人| 日本免费视频www| www.av在线视频| 欧美成人精品福利网站| 久草网在线视频| 国产女人伦码一区二区三区不卡| 黄色在线视频观看网站| 国产麻豆视频| 国产精品白浆视频免费观看| 91xx在线观看| 麻豆精品视频入口| 国产在线观看网站| 国产精品国产国产aⅴ| 中文资源在线网| 国产在线观看91| 国产精品186在线观看在线播放| 992tv在线观看在线播放| 日本在线视频www鲁啊鲁| 国产卡一卡二卡三| 992tv在线观看在线播放| 男人天堂网在线观看| 国产精品欧美色图| gogo在线观看| 136福利第一导航国产在线| 黄色毛片在线观看| 国产a国产a国产a| 亚洲www色| 国产一二三在线观看| 99色在线观看| 国产视频xxx| 国产在线一二三区| 精品国产丝袜高跟鞋| 91超碰国产在线| 日本不卡视频一区二区| 国产区视频在线观看| 亚洲成人电视网| 国产色在线 com| 国产永久免费高清在线观看| 一区二区精品区| 9999在线视频| 中文在线观看视频| 最近中文字幕mv免费高清在线| av小说在线| 999国产在线视频| 国产黄在线观看| 国产欧美在线观看视频| 午夜视频在线| 国产卡一卡二卡三| 黄污在线观看| 导航福利在线| 国产九色视频| 天天av天天爽| 国产一卡2卡3卡4卡网站免费| 男女午夜视频在线观看| www.狠狠操| 久久一本精品| 三级小说一区| 青青青国产视频| 九九热在线观看| 国产美女一区视频| 国产天堂素人系列在线视频| 国产精品入口麻豆完整版| 国产乱码在线| 国产a国产a国产a| 永久免费不卡在线观看黄网站| ·天天天天操| 青青九九免费视频在线| 九九免费视频| 最近高清中文在线字幕在线观看| 最新国产在线精品91尤物| 国产三区视频在线观看| 国产视频中文字幕| 91在线网址| 激情综合网五月激情| 国产小视频福利在线| 伊人伊人av电影| 国产美女av| 在线视频中文字幕| 国内自拍视频在线观看| 91在线超碰| 国产美女视频一区二区二三区| 国产成人精品18| 老司机在线视频二区| 69免费视频| 国产日本韩国在线播放| 麻豆国产在线播放| 国产无遮挡又黄又爽免费网站 | 综合激情亚洲| 9色在线视频网站| 精品资源在线看| 91九色在线看| 国产一卡二卡3卡4卡四卡在线| 亚洲欧美综合乱码精品成人网| 丁香花视频在线观看| 国产网红在线| 国产在线高潮| 日本福利午夜视频在线| 日韩av成人| 精品偷拍激情视频在线观看| 成年网站免费入口在线观看| 精精国产xxxx视频在线中文版| 黄色片免费在线| а√资源新版在线天堂| 精品卡一卡卡2卡3网站| 国产偷激情在线| 国产亚洲精品午夜高清影院| 国产免费一级| 最新中文字幕av专区| 国产麻豆视频网站| 天堂在线亚洲| 国产午夜视频在线观看| 最近免费中文字幕大全免费第三页| 亚洲日本久久久午夜精品| 国产成人无吗| 国产福利在线观看| 国产馆av播放| 国产高潮av| 亚洲欧美小说国产图片| 亚洲精品少妇久久久久久| 亚洲第一成年免费网站| 欧美日韩性视频一区二区三区| 亚洲妇熟xxxx妇色黄| 久久精品国产亚洲a∨麻豆| 福利视频网站导航| 国产婷婷视频在线| av大片在线播放| 亚洲xxxxxx| 91福利在线免费| 国产精品xxx电影| 精品视频麻豆入口| 激情五月色综合亚洲小说| 中文字幕在线免费看| 国产黄色片中文字幕| 伊人色综合网| 青青青手机在线视频观看| eeuss影院www在线播放| 国产日本在线视频| 精品99又大又爽又硬少妇毛片| 国产盗摄一区二区| 欧美亚洲系列| 国产极品美女到高潮| 在线视频二区| 99热在线观看免费| av大片在线| 国产黄大片在线观看画质优化| 欧美日韩在线视频免费观看| 国产精品jvid在线观看| 九九热在线免费视频|