Spring容器启动之finishBeanFactoryInitialization实例化所有非懒(延迟)加载的Bean流程
实例化所有非懒加载Bean
AbstractApplicationContext#finishBeanFactoryInitialization():
该方法主要负责从spring注册缓存中获取非懒加载类,进行实例化(getBean)
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
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();
}
方法总结:
1:判断容器三级缓存或BeanDefinition缓存是否存在数据转换器实例或Bean定义,存在则通过getBean() 实例化数据转换器 ConversionService.class,ConversionService是一个服务接口用于类型转换,这也是转换系统的入口点。
2:如果容器中没有后置处理程序,则注册一个默认的嵌入式解析器。(具体负责什么暂时不知道)
3:实例化容器中所有的 LoadTimeWeaverAware接口类型的类,以便尽早注册它们的转换器。LoadTimeWeaverAware是类加载时织入的意思。getBean则是让实现LoadTimeWeaverAware的对象提前实例化。
4:冻结之前beandifinition的配置,留作后面的缓存用
5:实例化所有的non-lazy-init单例,bean真正实例化的时刻到了
真正加载非懒加载Bean具体代码
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("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);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
DefaultListableBeanFactory#preInstantiateSingletons()总结:
- 获取注册Bean定义名称集合
- 循环Bean定义集合
2.1:合并Bean属性,遍历父Bean定义并赋给子Bean定义
2.2: 判断类是否满足如下条件: 非抽象类 && 单例 && 指定Lazy = false
2.2.1:否:懒加载类,不进行实例化getBean() 操作,
2.2.2:是:判断当前Bean是否是FactoryBean,如果是FactoryBean,继续判断FactoryBean是否懒加载,如果非懒加载,实例化FactoryBean 进行getBean()操作
如果不是FactoryBean,直接对该Bean进行getBean()操作。 - 循环BeanDefinition集合,获取Spring三级缓存中存在Bean实例(或者提前暴漏的工厂Bean),在这里只有是非懒加载的Bean都已经通过getBean方法进行了实例化,spring三级缓存中肯定都将上述的非懒加载Bean进行了保存,判断缓存中的Bean是否实现了SmartInitializingSingleton接口,若实现了该接口,执行该Bean的重写方法afterSingletonsInstantiated() ,相当与一个回调函数,可以在这个阶段对自定义Bean做一些特殊的处理流程。
finishBeanFactoryInitialization()大概调用的时序图