天天看點

spring 加載過程

這幾天在看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将從哪兒加載并知道加載哪些檔案了。