我是靠谱客的博主 狂野白昼,这篇文章主要介绍Spring启动流程源码之finishBeanFactoryInitialization一、finishBeanFactoryInitialization,现在分享给大家,希望可以做个参考。

        finishBeanFactoryInitialization是Spring启动中refresh方法里比较重要的最后一步,之前所有的准备和操作都是为了这步操作做的准备,我们直接去看源码分析。

 

一、finishBeanFactoryInitialization

finishBeanFactoryInitialization的源码在org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization下,内容如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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方法中,那么这个方法又做了哪些事情呢?我们接着往下看:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(90)

评论列表共有 0 条评论

立即
投稿
返回
顶部