一、refresh 方法
SpringBoot 加载 bean 操作主要在 AbstractApplicationContext 类 refresh 方法里,它的流程图如下:
代码如下:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 容器状态设置,初始化属性设置,检查必备属性是否存在
prepareRefresh();
// 设置beanFactory序列化id,获取beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 beanFactory 属性,添加后置处理器,设置忽略的自动装配接口,注册部分组件
prepareBeanFactory(beanFactory);
try {
// 子类重写以在 BeanFactory 完成创建后做进一步设置
postProcessBeanFactory(beanFactory);
// 调用BeanDefinitionRegistryPostProcessor实现向容器内添加bean的定义
// 调用BeanFactoryPostProcessor实现向容器内添加bean的定义添加属性
invokeBeanFactoryPostProcessors(beanFactory);
// 找到BeanPostPocessor的实现,排序后注册进容器内
registerBeanPostProcessors(beanFactory);
// 初始化国际化相关属性
initMessageSource();
// 初始化事件广播器。注册到容器当中
initApplicationEventMulticaster();
// 创建web容器。如果是web环境当中,构建一个web容器,如tomcat,jetty等。
onRefresh();
// 添加容器内事件监听器至事件广播器中
// 派发早期事件
registerListeners();
// 初始化剩下的单实例 Bean
registerListeners(beanFactory);
// 初始化生命周期处理器
// 调用生命周期处理器的onRefresh方法
// 发布ContextRefreshedEvent 事件
// JMX相关处理
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例
destroyBeans();
// 重置标记
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// 清除缓存
resetCommonCaches();
}
}
}
二、Bean实例化流程
bean 实例化流程流程是在 onRefresh方法的 finishBeanFactoryInitialization中,进入该方法:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}