概述
finishBeanFactoryInitialization是Spring启动中refresh方法里比较重要的最后一步,之前所有的准备和操作都是为了这步操作做的准备,我们直接去看源码分析。
一、finishBeanFactoryInitialization
finishBeanFactoryInitialization的源码在org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization下,内容如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//1、类型转换器,不重要
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
//2、注册解析器:用于读取配置文件中的内容,例如${},解析成真正的属性
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
//3、处理 @EnableLoadTimeWeaving 或 <context:load-time-weaver/> 标记的类
//作用:jvm加载时织入某些类,空的,不重要
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
//4、临时类加载器设置为空
beanFactory.setTempClassLoader((ClassLoader)null);
//5、冻结所有的bean,注册的bean定义不会被修改或进一步后处理,因为马上要进行创建bean的操作了
beanFactory.freezeConfiguration();
//6、创建bean,重要
beanFactory.preInstantiateSingletons();
}
由上面源码可以看出finishBeanFactoryInitialization方法中前面都是仍然是在做一些准备,最最重要的方法依然是在preInstantiateSingletons方法中,那么这个方法又做了哪些事情呢?我们接着往下看:
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
//注意:以下懒加载、抽象、非singletons是不需要初始化的,因此不会调用getBean
//判断是否是懒加载
do {
//判断是否不是singletons
do {
//判断是否是抽象
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
//如果bean实现了 SmartInitializingSingleton 接口,在这里会回调它的afterSingletonsInstantiated方法
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
//在这一步会先去根据name返回BeanDefinition,然后去处理属性继承和覆盖的关系,获取最终的属性
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
//约定俗成,如果是FactoryBean需要在前面加上'&',再去调用getBean
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
//调用前置后置处理器、实例化、填充、反射,都在这个getBean里!
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
//处理FactoryBean
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
//判断当前 FactoryBean 是否是 SmartFactoryBean 的实现,此处忽略,直接跳过
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
从上面两个源码我们很容易发现,preInstantiateSingletons方法中的主要流程如下:
至此,Spring启动流程的refresh方法就介绍完了,至于getBean、doGetBean、createBean、doCreateBean这些创建bean的源码解析可以看我的另外一篇文章【Spring】Spring中的三级缓存及循环依赖的问题
最后
以上就是狂野白昼为你收集整理的Spring启动流程源码之finishBeanFactoryInitialization一、finishBeanFactoryInitialization的全部内容,希望文章能够帮你解决Spring启动流程源码之finishBeanFactoryInitialization一、finishBeanFactoryInitialization所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复