創建ApplicationContext有兩種方式,最常用的一種方式就是以聲明的方式創建,如使用ContextLoader,這也是絕大多數web應用採用的一種方式。另一種方式就是用ApplicationContext的藉口實現類以編程的方式實現。
在這裏我主要講一下聲明方式的實現及其原理:
首先講一下ContextLoader接口,它有兩個實現:ContextLoaderListener 和ContextLoaderServlet.其中常用的是ContextLoaderListener.從spring 文檔上可以查到,他們二者實現的功能基本一樣,只是ContextLoaderListener不能在與Servlet2.2兼容的web容器中使用。另外,因爲ContextLoaderLitener是一個servlet Listener,因此,它是在servlet context建立後立即執行,也就以爲這servlet已建立,spring的ApplicationContext就得到了初始化,並且能夠相應第一個請求,所以首選ContextLoaderListener.
下面是一個項目的web.xml文件的部分代碼:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Baselib Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/spring-sup-middelbeans.xml
/WEB-INF/classes/spring-ueaac-action.xml
/WEB-INF/classes/spring-ueaac-beans.xml
/WEB-INF/classes/spring-ueaac-cm.xml
/WEB-INF/classes/spring-ueaac-hibernate.xml
/WEB-INF/classes/spring-ueaac-resource.xml
/WEB-INF/classes/spring-ueaac-sso.xml
/WEB-INF/classes/com/javaeye/jert/application_context.xml
</param-value>
</context-param>
…………………………
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
…………………
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Baselib Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/spring-sup-middelbeans.xml
/WEB-INF/classes/spring-ueaac-action.xml
/WEB-INF/classes/spring-ueaac-beans.xml
/WEB-INF/classes/spring-ueaac-cm.xml
/WEB-INF/classes/spring-ueaac-hibernate.xml
/WEB-INF/classes/spring-ueaac-resource.xml
/WEB-INF/classes/spring-ueaac-sso.xml
/WEB-INF/classes/com/javaeye/jert/application_context.xml
</param-value>
</context-param>
…………………………
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
…………………
這裏主要是配置了spring的監聽器ContextLoaderListener,它檢查contextConfigLocation 這個參數。如果它不存在的話,它將用/WEB-INF/applicationContext.xml 作爲默認的配置文件。如果contextConfigLocation存在的話,它將根據該參數的值查找配置文件的位置,來一一讀取spring參數。
在這裏要注意一個問題(個人觀點,不知對錯),關於參數名稱contextConfigLocation ,我個人認爲是固定的,不能隨意改動,因爲我曾經做過試驗,發現回出錯,這時候監聽器找不到contextConfigLocation參數,則用默認值,即它會去查找appilcationContext.xml文件,這時當然會抱錯的拉。爲了更有說服力,我查閱了一下spring源碼,下面是ContextLoader.java的部分源碼:
package org.springframework.web.context;
publicclass ContextLoader {
publicstaticfinal String CONTEXT_CLASS_PARAM = "contextClass";
/**
*Nameofservletcontextparameterthatcanspecifytheconfiglocation
*fortherootcontext,fallingbacktotheimplementation'sdefault
*otherwise.
*
*/
publicstaticfinal String CONFIG_LOCATION_PARAM = "contextConfigLocation";
publicstaticfinal String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
publicstaticfinal String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
privatestaticfinal String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
privatestaticfinal Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
thrownew IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
}
}
…………………………………………………
publicclass ContextLoader {
publicstaticfinal String CONTEXT_CLASS_PARAM = "contextClass";
/**
*Nameofservletcontextparameterthatcanspecifytheconfiglocation
*fortherootcontext,fallingbacktotheimplementation'sdefault
*otherwise.
*
*/
publicstaticfinal String CONFIG_LOCATION_PARAM = "contextConfigLocation";
publicstaticfinal String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
publicstaticfinal String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
privatestaticfinal String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
privatestaticfinal Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
thrownew IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
}
}
…………………………………………………
其中有一個屬性
publicstaticfinal String CONFIG_LOCATION_PARAM = "contextConfigLocation";
說明了contextConfigLocation是被spring固定的,專門用來查 找配置文件位置的