决战圣地玛丽乔亚Day41 ----Spring启动流程之refresh()源码分析
3.this.refresh():
refresh的整体结构
1.Spring应用上下文启动准备阶段
this.prepareRefresh();
记录了应用程序的启动时间,并设置为活跃状态。
根据日志的打印规范打印所需内容
初始化属性(系统变量、环境变量、配置文件等)并进行验证。
这段代码:
如果早期监听器存在,说明早期阶段注册了监听器,就把监听器集合清空,把早期监听器存进去。
如果早起监听器不存在,说明早期没有注册任何事件监听器,就把监听器集合赋给早期监听器。
监听器的作用:
ApplicationListener可以让相匹配的事件自动调用onApplicationEvent方法。
最后new一个空的earlyApplicationEvents()集合
2.BeanFactory创建阶段
这里的refreshed用了原子类
如果重复刷新,会报错抛出,如果没有重复刷新过,设置BeanFactory的序列化id。
通过原子变量refreshed判断是否刷新过。
BeanFactory的序列化id以便反序列化进行核实。
为什么BeanFactory需要被反序列化?
BeanFactory需要反序列化的原因是,BeanFactory在应用程序运行过程中可能会被序列化到磁盘或通过网络传输,在反序列化时需要重新加载Bean定义以及相关的配置信息,以便重新创建Bean实例。例如,在分布式应用程序中,BeanFactory可能会被序列化到远程服务器上,并在远程服务器上反序列化并重新创建Bean实例,以提供服务。
3.BeanFactory准备阶段
this.prepareBeanFactory(beanFactory);
设置当前应用程序的ClassLoader为BeanFactory的ClassLoader。
设置BeanFactory的表达式解析器为StandardBeanExpressionResolver,并将BeanFactory的ClassLoader作为参数传递给解析器。
注册一个ResourceEditorRegistrar,用于将资源文件转换为Resource对象。
后置处理器添加一个ApplicationContextAwareProcessor,用于在Bean创建过程中注入ApplicationContext对象。
忽略这些接口,不会自动注入到bean,需要手动注入到bean中
注册一个ResolvableDependency,用于解决BeanFactory、ResourceLoader、ApplicationEventPublisher和ApplicationContext的依赖关系。
为这个beanFactory添加bean的后置处理
添加一个ApplicationListenerDetector,用于检测Bean是否实现了ApplicationListener接口
如果BeanFactory中包含名为"loadTimeWeaver"的Bean,则添加一个LoadTimeWeaverAwareProcessor,
用于在Bean创建过程中注入LoadTimeWeaver对象,并设置临时ClassLoader为ContextTypeMatchClassLoader。
如果BeanFactory中不包含名为"environment"、"systemProperties"和"systemEnvironment"的Bean,则注册这三个Bean。其中,"environment"为当前应用程序的环境对象,"systemProperties"为系统属性对象,"systemEnvironment"为系统环境对象。
在准备阶段有两个addBeanPostProcessor后置处理器,一个是
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
来看一下这两个处理器是用来干什么的。
ApplicationContextAwareProcessor:如果bean实现了ApplicationContextAware接口,则调用setApplicationContext方法将ApplicationContext对象注入到Bean中。
ApplicationListenerDetector:如果Bean实现了ApplicationListener接口,则ApplicationListenerDetector会将该Bean添加到Spring事件监听器列表中,以便在事件发生时执行相应的处理逻辑。
关于Aware接口的作用:
1.标记接口,实现该接口一般会有一个BeanPostProcessor类对其处理
2.具体方法的定义由实现了该接口的子接口进行定义,但是通常该子接口应该只包含一个方法,且该方法的返回值为void,参数只有一个
4.BeanFactory后置处理阶段
这里没有做任何处理,可以通过重写的方式进行处理或者实现BeanFactoryPostProcessor接口
5.BeanFactory注册BeanPostProcessor阶段
this.getBeanFactoryPostProcessors是返回所有已注册的BeanFactoryPostProcessor实现类
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors())的作用是:
调用所有注册到BeanFactoryPostProcessor接口的实现类的postProcessBeanFactory方法,对BeanFactory进行进一步的配置和修改。
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet(); ArrayList regularPostProcessors; ArrayList registryProcessors; int var9; ArrayList currentRegistryProcessors; String[] postProcessorNames; if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory; regularPostProcessors = new ArrayList(); registryProcessors = new ArrayList(); Iterator var6 = beanFactoryPostProcessors.iterator(); while (var6.hasNext()) { BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next(); if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } currentRegistryProcessors = new ArrayList(); postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor. class , true , false ); String[] var16 = postProcessorNames; var9 = postProcessorNames.length; int var10; String ppName; for (var10 = 0 ; var10 < var9; ++var10) { ppName = var16[var10]; if (beanFactory.isTypeMatch(ppName, PriorityOrdered. class )) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor. class )); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor. class , true , false ); var16 = postProcessorNames; var9 = postProcessorNames.length; for (var10 = 0 ; var10 < var9; ++var10) { ppName = var16[var10]; if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered. class )) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor. class )); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); boolean reiterate = true ; while (reiterate) { reiterate = false ; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor. class , true , false ); String[] var19 = postProcessorNames; var10 = postProcessorNames.length; for ( int var26 = 0 ; var26 < var10; ++var26) { String ppName = var19[var26]; if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor. class )); processedBeans.add(ppName); reiterate = true ; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory); invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory); } else { invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory); } String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor. class , true , false ); regularPostProcessors = new ArrayList(); registryProcessors = new ArrayList(); currentRegistryProcessors = new ArrayList(); postProcessorNames = postProcessorNames; int var20 = postProcessorNames.length; String ppName; for (var9 = 0 ; var9 < var20; ++var9) { ppName = postProcessorNames[var9]; if (!processedBeans.contains(ppName)) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered. class )) { regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor. class )); } else if (beanFactory.isTypeMatch(ppName, Ordered. class )) { registryProcessors.add(ppName); } else { currentRegistryProcessors.add(ppName); } } } sortPostProcessors(regularPostProcessors, beanFactory); invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size()); Iterator var21 = registryProcessors.iterator(); while (var21.hasNext()) { String postProcessorName = (String)var21.next(); orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor. class )); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size()); Iterator var24 = currentRegistryProcessors.iterator(); while (var24.hasNext()) { ppName = (String)var24.next(); nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor. class )); } invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory); beanFactory.clearMetadataCache(); } |
具体细节:
入参 beanFactoryPostProcessors:这个值拿的是 AbstractApplicationContext 类的 beanFactoryPostProcessors 属性值,也就是在之前已经添加到 beanFactoryPostProcessors 中的 BeanFactoryPostProcessor
实现 BeanDefinitionRegistryPostProcessor.class 接口的 Bean:实现了 BeanDefinitionRegistryPostProcessor 接口,并且 Bean 定义已经存入了 beanFactory 中
实现 BeanFactoryPostProcessor.class 接口的 Bean:实现了 BeanFactoryPostProcessor接口,并且 Bean 定义已经存入了 beanFactory 中
处理这三种 Bean 的流程也就是执行这些 Bean 中重写的 BeanFactoryPostProcessor 相关方法,那具体的执行顺序如下:
第一优先级:入参 beanFactoryPostProcessors 中的 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry 方法
第二优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanDefinitionRegistry 方法
第三优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanDefinitionRegistry 方法
第四优先级:除去第二优先级和第三优先级,剩余的 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanDefinitionRegistry 方法
第五优先级:所有 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanFactory 方法
第六优先级:入参 beanFactoryPostProcessors 中的常规 BeanFactoryPostProcessor,调用 postProcessBeanFactory 方法
第七优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanFactory 方法
第八优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanFactory 方法
第九优先级:除去第七优先级和第八优先级,剩余的常规 BeanFactoryPostProcessor 接口的实现类,调用 postProcessBeanFactory 方法
其实也就是分为两类,一类是BeanDefinitionRegistryPostProcessor ,另一类是BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor的执行顺序是在所有的BeanFactoryPostProcessor之前,因此它可以对所有的BeanDefinition进行修改。
接下来就是registerBeanPostProcessors
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 | public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor. class , true , false ); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor( new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList(); List<BeanPostProcessor> internalPostProcessors = new ArrayList(); List<String> orderedPostProcessorNames = new ArrayList(); List<String> nonOrderedPostProcessorNames = new ArrayList(); String[] var8 = postProcessorNames; int var9 = postProcessorNames.length; String ppName; BeanPostProcessor pp; for ( int var10 = 0 ; var10 < var9; ++var10) { ppName = var8[var10]; if (beanFactory.isTypeMatch(ppName, PriorityOrdered. class )) { pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor. class ); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered. class )) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors); List<BeanPostProcessor> orderedPostProcessors = new ArrayList(orderedPostProcessorNames.size()); Iterator var14 = orderedPostProcessorNames.iterator(); while (var14.hasNext()) { String ppName = (String)var14.next(); BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor. class ); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors); List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList(nonOrderedPostProcessorNames.size()); Iterator var17 = nonOrderedPostProcessorNames.iterator(); while (var17.hasNext()) { ppName = (String)var17.next(); pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor. class ); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors); sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, (List)internalPostProcessors); beanFactory.addBeanPostProcessor( new ApplicationListenerDetector(applicationContext)); } |
BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它。
BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。
1.找出所有实现BeanPostProcessor接口的类
2.添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
6.初始化内建Bean:MessageSource
国际化相关的内容
7.初始化内建Bean:Spring事件广播器
先判断有没有自定义的ApplicationEventMulticaster,没有的话就注册一个,即new 一个SimpleApplicationEventMulticaster,用来发布事件。
8.Spring应用上下文刷新阶段
模板方法,留给子类扩展用的。
9.Spring事件监听器注册阶段
- 添加当前应用上下文所关联的ApplicationListener对象
- 添加BeanFactory所注册的ApplicationListener
- 广播早期Spring事件
10.BeanFactory初始化完成阶段
- 设置转换服务:如果BeanFactory中包含名为"conversionService"的Bean,并且该Bean的类型是ConversionService,则将该Bean设置为BeanFactory的转换服务。
- 添加嵌入式值解析器:如果BeanFactory没有嵌入式值解析器,则添加一个解析器,用于解析属性中的占位符(如"${...}")。
- 处理LoadTimeWeaverAware:查找所有实现了LoadTimeWeaverAware接口的Bean,并强制初始化它们,以便在BeanFactory启动时激活LoadTimeWeaver。
- 设置临时类加载器:将BeanFactory的临时类加载器设置为null,这意味着BeanFactory将使用默认的类加载器。
- 冻结配置:冻结BeanFactory的配置,以防止其他BeanFactoryPostProcessor对其进行更改。
- 预实例化单例:预实例化所有非懒加载的单例Bean,以便在应用程序启动时立即初始化它们。
finishBeanFactoryInitialization的作用是确保BeanFactory的正确配置和初始化,以便程序启动可以正常使用所有的bean。
11.Spring应用上下文启动完成阶段
- 清除资源缓存:清除Spring应用程序上下文中的资源缓存,包括所有的类元数据缓存和Bean名称缓存。
- 初始化生命周期处理器:初始化应用程序上下文的生命周期处理器,它负责管理应用程序上下文中所有bean的生命周期。
- 调用生命周期处理器的onRefresh方法:通知生命周期处理器,应用程序上下文已经刷新完成,可以开始启动应用程序中的生命周期bean。
- 发布ContextRefreshedEvent事件:在应用程序上下文刷新完成后,发布ContextRefreshedEvent事件,这将通知所有已注册的事件监听器,应用程序上下文已经准备好使用。
- 注册LiveBeansView:如果LiveBeansView功能已经启用,则在JMX中注册ApplicationContext,以便可以使用JConsole查看应用程序上下文中的所有bean。
总的来说,finishRefresh方法主要是为了在应用程序上下文刷新完成后,进行一些必要的清理和初始化工作,以便应用程序可以正常地运行,并且可以及时通知其他组件,应用程序已经准备好可以使用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2021-03-26 Java-Core
2021-03-26 时隔多年那些想说的话。