简介
SmartInitializingSingleton是spring的扩展点之一,主要用于在Spring容器启动完成时进行扩展操作,其只有一个方法afterSingletonsInstantiated()。
触发的关键点是在单例预实例化阶段结束时调用,保证所有常规单例 bean 都已创建。接口的bean的作用域必须是单例才会触发。
扩展接口 | 实现接口 |
---|---|
ApplicationContextlnitializer | initialize |
AbstractApplicationContext | refreshe |
BeanDefinitionRegistryPostProcessor | postProcessBeanDefinitionRegistry |
BeanDefinitionRegistryPostProcessor | postProcessBeanFactory |
BeanFactoryPostProcessor | postProcessBeanFactory |
instantiationAwareBeanPostProcessor | postProcessBeforelnstantiation |
SmartlnstantiationAwareBeanPostProcessor | determineCandidateConstructors |
MergedBeanDefinitionPostProcessor | postProcessMergedBeanDefinition |
InstantiationAwareBeanPostProcessor | postProcessAfterlnstantiation |
SmartInstantiationAwareBeanPostProcessor | getEarlyBeanReference |
BeanFactoryAware | postProcessPropertyValues |
ApplicationContextAwareProcessor | invokeAwarelnterfaces |
BeanNameAware | setBeanName |
InstantiationAwareBeanPostProcessor | postProcessBeforelnstantiation| |
BeanNameAware | setBeanName |
@PostConstruct | |
InitializingBean | afterPropertiesSet |
FactoryBean | getobject |
SmartlnitializingSingleton | afterSingletonslnstantiated |
CommandLineRunner | run |
DisposableBean | destroy |
源码分析
方法 preInstantiateSingletons
实例化非懒加载的单例Bean
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// 如果实例实现了SmartInitializingSingleton,执行afterSingletonsInstantiated方法。
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
// 所有的非懒加载单例bean都创建完成之后调用
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
应用场景
SmartInitializingSingleton 提供了一种在所有单例 Bean 实例化后但在应用完全启动之前执行自定义逻辑的机制。它主要用于那些需要在所有 Bean 完全实例化后进行全局初始化、处理依赖关系、配置外部库或确保初始化顺序的场景。
示例代码
@Slf4j
@Configuration
public class ExtendSmartInitializingSingleton implements SmartInitializingSingleton {
private ListableBeanFactory beanFactory;
public ExtendSmartInitializingSingleton(ListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public void afterSingletonsInstantiated() {
String[] beanNames = beanFactory.getBeanNamesForType(TestAutowired.class);
for (String s : beanNames) {
log.info("=================================");
log.info(s);
}
}
}