1.監聽器
public class ContextLoaderListener extends ContextLoader implements ServletContextListener
ContextLoaderListener 是spring-web中的類,實現了servlet-api中的接口ServletContextListener ,繼承了
spring-web中ContextLoader
該類重要是實現接口中的contextInitialized方法,該類主要是監聽ServletContext(應用上下文)的創建和銷燬,當創建時初始化Spring容器,而實際的執行方法initWebApplicationContext是定義在父類ContextLoader,創建一個web容器類.
2.Spring容器的存放
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
把生成的Spring容器存放到servletCotext上下文中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
所以引申出是否已經存在spring容器的判斷
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!");
}
知道了spring容器的位置,我們就可以獲取到spring容器,從而獲取到被容器管理的bean.
3.Spring容器的創建
ContextLoader 類中的createWebApplicationContext用來創建容器,是通過反射來創建
//這段代碼是在ContextLoader.initWebApplicationContext方法中
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
但是容器的實現類有很多,所以需要判斷到底用哪一個實現類
所以在createWebApplicationContext方法中出現這段代碼
//該方法用來確定到底使用哪一個實現類
Class<?> contextClass = determineContextClass(sc);
- 實現類的字符串可以定義在web.xml的context-param的標籤中.
- 定義在ContextLoader.properties文件中,這是一個默認的配置文件.
ContextLoader.properties 的位置,在jar包中
org/springframework\web\context\ContextLoader.properties
ContextLoader.properties 的內容
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
4.返回容器
判斷ConfigurableWebApplicationContext是否是XmlWebApplicationContext的父類,返回容器
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);