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中并没有调用此方法。