一. 介绍
实现了 SmartInitializingSingleton 接口的 bean,当所有单例 bean 都已完全初始化后,该接口的 afterSingletonsInstantiated() 会被回调;
SmartInitializingSingleton 和 InitializingBean、@PostContruct 有啥区别呢?
- SmartInitializingSingleton 是容器级别的,确保在所有 bean 初始化后才执行;
- InitializingBean 和 @PostContruct 是 bean 级别的初始化回调;
二. 简单使用
先来看一下 SmartInitializingSingleton 接口;
可以看到该接口只有一个抽象方法;
public interface SmartInitializingSingleton {
void afterSingletonsInstantiated();
}
举一个使用例子,定义一个 MySmartInitializingSingleton 类实现了 SmartInitializingSingleton 接口;
@Component
@Slf4j
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
log.info("所有的单实例 bean 加载完成");
}
}
容器启动时,在所有单实例都初始化完毕后,SmartInitializingSingleton 的 afterSingletonsInstantiated() 回调方法会执行;
三. 源码
我们需要知道 SmartInitializingSingleton 接口的 afterSingletonsInstantiated() 回调方法的执行时机,直接看 SpringBoot 项目的执行入口,也就是 SpringApplication.run();
// -------------------------- SpringApplication -----------------------------
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新 context 容器对象
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
listeners.started(context, timeTakenToStartup);
this.callRunners(context, applicationArguments);
} catch (Throwable var12) {
this.handleRunFailure(context, var12, listeners);
throw new IllegalStateException(var12);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
// 返回容器对象
return context;
} catch (Throwable var11) {
this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var11);
}
}
// -------------------------- SpringApplication -----------------------------
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
// ------------------------ AbstractApplicationContext ------------------------
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
// 我们主要看这个方法
// 该方法将所有非懒夹杂单实例 bean 对象初始化并放到 beanFactory 容器中
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
}
}
// ------------------------ AbstractApplicationContext ------------------------
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// ......
// 将所有的非懒加载单例 bean 初始化并放入到 beanFactory 容器中
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
核心方法是 beanFactory.preInstantiateSingletons();
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 1. 拿到所有的 beanDefinitionNames,可以看到它是一个有先后顺序的 List
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 2. 初始化所有的非懒加载单实例对象
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// ...
// FactoryBean
}
else {
getBean(beanName);
}
}
}
// 3. 再次遍历 beanNames,
// 执行 SmartInitializingSingleton.afterSingletonsInstantiated()
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = singletonInstance;
smartSingleton.afterSingletonsInstantiated();
}
}
}
至此,SmartInitializingSingleton.afterSingletonsInstantiated() 执行时机完毕;