03.Spring IoC 容器 - 初始化
阿新 • • 發佈:2018-07-22
itl ret num servlet fontsize eat 圖片 number sources
基本概念
Spring IoC 容器的初始化過程在監聽器 ContextLoaderListener 類中定義。
具體由該類的的 configureAndRefreshWebApplicationContext 方法實現,它包含了兩個過程:
- 配置過程
- 刷新過程
原理分析
下面來看 configureAndRefreshWebApplicationContext 方法的具體實現:
// 表示容器的標識
public static final String CONTEXT_ID_PARAM = "contextId";
// 表示容器的配置文件路徑
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
protected void configureAndRefreshWebApplicationContext(
ConfigurableWebApplicationContext wac, ServletContext sc) {
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
// 配置過程:
// 1.設置容器的標識,即 ContextId
String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
if (idParam != null) {
wac.setId(idParam);
}else {
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getContextPath()));
}
}
// 2.設置容器的 ServletContext
wac.setServletContext(sc);
// 3.設置容器的配置文件路徑,即 ContextConfigLocation
String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocationParam != null) {
wac.setConfigLocation(configLocationParam);
}
// 4.設置容器的環境,並初始化它的屬性
ConfigurableEnvironment env = wac.getEnvironment();
// 5.初始化容器的環境屬性
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
}
// 自定義過程,暫不探究
customizeContext(sc, wac);
// 刷新過程:
wac.refresh();
}
Spring 容器的初始化過程實際被細分為了兩個過程:配置過程、刷新過程
-
在 ContextLoaderListener 類中主要完成了配置過程,即設置容器的 ContextId,ServletContext,ConfigLocation,ConfigurableEnvironment 屬性等。
-
刷新的過程則由剛剛創建 Spring 容器自己完成。
配置過程
1.設置容器的環境
Spring 容器在設置的它的 Environment 屬性時,如果不存在則默認創建一個 StandardServletEnvironment對象。具體的繼承關系如下:
來看下 getEnvironment 方法:
private ConfigurableEnvironment environment;
public ConfigurableEnvironment getEnvironment() {
// 不存在,則創建
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
return new StandardServletEnvironment();
}
再來分析 StandardEnvironment 的初始化過程,該類在初始化過程中,會創建一個 propertySources 對象來保存系統相關的環境變量與屬性。
// AbstractEnvironment 類
private final MutablePropertySources propertySources =
new MutablePropertySources(this.logger);
public AbstractEnvironment() {
customizePropertySources(this.propertySources);
// 省略部分代碼...
}
// StandardEnvironment 類
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME ="systemEnvironment";
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(
new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME,
getSystemProperties()));
propertySources.addLast(
new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
getSystemEnvironment()));
}
2.初始化容器的環境屬性
即初始化 Environment 的 propertySources 屬性,它會將 ServletContext 、ServletConfig 添加到
propertySources 中。
// StandardServletEnvironment 類
public void initPropertySources(ServletContext servletContext,
ServletConfig servletConfig) {
// 將 servletContext、servletConfig 添加到 propertySources
WebApplicationContextUtils.initServletPropertySources(
getPropertySources(),servletContext, servletConfig);
}
public MutablePropertySources getPropertySources() {
return this.propertySources;
}
03.Spring IoC 容器 - 初始化