0
点赞
收藏
分享

微信扫一扫

IOC容器初始化过程中单例Bean的预实例化

在容器的refresh方法中我们可以看到finishBeanFactoryInitialization方法,该方法就是实例化所有非懒加载实例
IOC容器初始化过程中单例Bean的预实例化_Bean的预实例化
IOC容器初始化过程中单例Bean的预实例化_Bean的预实例化_02

① finishBeanFactoryInitialization

AbstractApplicationContext的​​finishBeanFactoryInitialization​​​方法封装了对lazy-init属性的处理,实际处理部分是在​​DefaultListableBeanFactory​​​的​​preInstantiateSingletons​​方法中完成的。该方法对单例Bean完成预实例化,这个预实例化的完成巧妙地委托给容器来实现。

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();
}

② preInstantiateSingletons

这里获取所有的beanDefinitionNames,如果其非抽象、是单例、未配置lazy_init属性或其值非true那么就会触发getBean的操作。比如前面图片中我们的swiperController就是在这里被实例化的。

@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) {
final 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);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

方法解释如下:

  • ① 拿到所有的beanDefinitionNames
  • ② 遍历beanNames,其非抽象、是单例、未配置lazy_init属性或其值非true那么就会触发getBean的操作;
  • ③ 遍历上面预实例化的单例bean,判断是否为SmartInitializingSingleton ;如果是,则调用其afterSingletonsInstantiated方法。

​SmartInitializingSingleton​​​提供一个在所有Bean都创建后才调用的初始化方法​​afterSingletonsInstantiated​​​。与​​InitializingBean​​​区别是其被触发的时机在所有单例bean都被实例化后,才会逐个触发​​SmartInitializingSingleton​​​的​​afterSingletonsInstantiated​​方法。


举报

相关推荐

0 条评论