這幾天在看spring的源碼,涉及到spring啟動位置的部分,下面就看看spring到底是從哪兒開始加載的。本文使用的是spring3.0M3
首先spring的加載會借助一個監聽器ContextLoaderListener,直接上web.xml檔案
Xml代碼
1.<listener>
2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
3.</listener>
我們通常會對加載位置統一管理
Xml代碼
1.<context-param>
2. <param-name>contextConfigLocation</param-name>
3. <param-value>
4. /WEB-INF/conf/spring*.xml
5. </param-value>
6. </context-param>
這個org.springframework.web.context.ContextLoaderListener類型是springframework中的原始加載上下文的監聽器,
通常我們會自定義一個Listener去繼承ContextLoaderListener并另外實作我們需要初始化的接口(通常我們會選擇實作一些接口來對session的管理)
Java代碼
1.public class FrameServletContextListener extends ContextLoaderListener implements ServletContextListener,HttpSessionAttributeListener,HttpSessionListener {
2. //
3. private ServletContext initPath(ServletContextEvent event) {
4.
5. }
6.
7. public synchronized void contextDestroyed(ServletContextEvent event) {
8. //
9. }
10.
11. ...
12.}
當監聽器設定好了之後 ,啟動web容器 監聽器開始啟動ContextLoaderListenerl
類中的方法contextInitialized()
Java代碼
1.
4.public void contextInitialized(ServletContextEvent event) {
5. this.contextLoader = createContextLoader();
6. if (this.contextLoader == null) {
7. this.contextLoader = this;
8. }
9. this.contextLoader.initWebApplicationContext(event.getServletContext());
10.}
這樣this.contextLoader.initWebApplicationContext(event.getServletContext());ContextLoaderListener
就會借助容器的上下文去初始一個spring的應用上下文,使用到了ContextLoader這個類
在ContextLoader初始化時我們看到這樣一塊static代碼
Java代碼
1.static {
2. // Load default strategy implementations from properties file.
3. // This is currently strictly internal and not meant to be customized
4. // by application developers.
5. try {
6. //這一句會去加載同在此包下的一個properties檔案的值(ContextLoader.properties)
7. ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
8. defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
9. }
10. catch (IOException ex) {
11. throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
12. }
13.}
屬性檔案中這樣定義
引用
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
這樣我們就能根據屬性檔案中的定義反射出一個XmlWebApplicationContext上下文了
然而我們在XmlWebApplicationContext中看到如下變量
Java代碼
1.
2.public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
至此我們已經知道預設加載spring檔案的啟動位置了
當我們再看ContextLoader類,我們就會看到傳說中的參數contextConfigLocation
Java代碼
1.public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
而XmlWebApplicationContext對象正是調用了這個參數去設定啟動位置
Java代碼
1.wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
再往上看XmlWebApplicationContext繼承的AbstractRefreshableConfigApplicationContext類中的setConfigLocation方法将此抽象類中的String[] configLocations值填充
并在AbstractRefreshableConfigApplicationContext類中我們看到spring對預設啟動檔案位置和配置啟動檔案位置的支援
Java代碼
1.protected String[] getConfigLocations() {
2. return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
}
至此我們已經清楚spring将從哪兒加載并知道加載哪些檔案了。