Spring ApplicationContext refresh方法(一)
目錄
prepareRefresh
prepareRefresh方法同樣是抽象類AbstractApplicationContext方法實現的。
見字知意,此方法就是爲spring的啓動做準備。
首先設置AtomicBoolean原子標誌位closed/active。
initPropertySources
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
//
//
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
抽象類中的initPropertySources
並未實現任何代碼,而是爲子類提供了擴展點。
通過使用ide可以發現org.springframework.web.context.support.StaticWebApplicationContext
對此進行了實現。
通過名字可以知道是讀取環境中的配置用於初始化Servlet相關的屬性。
@Override
protected void initPropertySources() {
WebApplicationContextUtils.initServletPropertySources(getEnvironment().getPropertySources(),
this.servletContext, this.servletConfig);
}
public static void initServletPropertySources(MutablePropertySources sources,
@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
Assert.notNull(sources, "'propertySources' must not be null");
String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletContextPropertySource(name, servletContext));
}
name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
}
}
getEnvironment().validateRequiredProperties()
getEnvironment
方法是獲取環境,null則會返回new StandardEnvironment()
StandardEnvironment繼承AbstractEnvironment,在父類空參構造時會調用
customizePropertySources(this.propertySources);
,此方法同樣父類未實現由子類重寫。
//systemProperties ,systemEnvironment
@Override
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()));
}
StandardEnvironment
中MutablePropertySources
包含一個PropertySource的數組。數組類使用的是CopyOnWriteArrayList,其內部使用ReentrantLock保證併發下的順序性。具體可以查看具體資料。
private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>();
回到customizePropertySources
方法,方法中向propertySourceList中增加了MapPropertySource
,SystemEnvironmentPropertySource
兩個的實現類。
properties是jvm參數,env是操作系統環境變量。
validateRequiredProperties
validateRequiredProperties校驗當前環境中是否缺少必要的參數,必要的參數是通過org.springframework.core.env.AbstractEnvironment#setRequiredProperties
設置進去的,這也是一個擴展點,spring refresh中並沒有調用此方法。