public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
synchronized (this.startupShutdownMonitor);确保了同一时间startupShutdownMonitor的状态不发生改变。
prepareRefresh();方法代码如下
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
synchronized (this.activeMonitor) {
this.active = 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
this.environment.validateRequiredProperties();
}
记录日期,设置活动状态,保证activeMonitor的状态不发生改变,同一时间只允许一次实例化,打印Refeshing+本方法信息,调用initPropertySources,但该方法没有实现任何操作等待子类实现,调用ConfigurableEnvironment的validateRequiredProperties();该方法属于抽象方法,位于ConfigurablePropertyResolver接口内,等待子类实现该方法。
从上面这个方法可以管中窥豹,Spring框架的技巧之一就是接口编程,全部都是接口方法,所有的功能组装都是运行期编译,维护一个样子,但还未充实它。