前面讲了Spring Boot基于JavaConfig的执行流程,主要讲了应用环境的准备和初始化、应用上下文的实例化和准备,在应用上下文实例化时只注册了为后续解析配置必要的bean,应用上下文中基本上没有任何东西。本文通过分析AbstractApplicationContext#refresh()
的执行来对Spring Boot的应用上下文的配置进行讲解,同时说明Spring Boot自动配置的实现。
AbstractApplicationContext#refresh()
的代码及关键代码和注释如下 :
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 为应用上下文的刷新做准备--设置时间、记录刷新日志、初始化属性源中的占位符(事实上什么都没做)和验证必
// 要的属性等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 让子类刷新内部的bean factory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备在这个应用上下文中使用的bean factory
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// bean factory 后置处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用应用上下文中作为bean注册的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册拦截创建bean的bean处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化消息源
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件广播
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 初始化特定上下文子类中的其它bean
onRefresh();
// Check for listener beans and register them.
// 注册监听器bean
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有的单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发布相应的事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);