背景:
一般面试官问到Spring都会问到Spring的生命周期。如何回答呢?
知识储备:
了解如 BeanDefinition、BeanFactoryPostProcessor、BeanPostProcessor、Aware等概念的作用。
注:源码跟踪示例使用配置文件方式 毕竟使用的方式千篇一律 有趣的原理才是万里挑一
提示:源码跟踪禁忌抠每一行代码 弄清源码功能整体的脉络思路就好
首先我们要启动Spring容器、可以通过读取xml方式、或者注解方式、甚至xml和注解结合的方式 启动容器。具体的Bean的生命周期如下:
流程:
- obtainFreshBeanFactory方法 获取一个Bean工厂。 这个方法核心做了三件事情
①创建工厂对象DefaultListableBeanFactory。ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
②给工厂设置一些属性 如allowCircularReferences 是否允许循环引用就是在这里设置的。
③loadBeanDefinitions加载Bean的定义信息、这里的方法非常复杂、各种方法的重载、doucumet ---> element --> parseDefaultElemet、parseCustomerElement、不管怎么说会读取xml文件的一些标签信息。最终会把这些信息封装成GenericBeanDefinition加载到Spring容器BeanDefinitionNames和BeanDefinitionMap中,方便后续Bean的初始化工作。
- prepareBeanFactory 核心就是给Bean工厂设置一些参数、为了后续创建Bean做准备。
- InvokeBeanFactoryBeanPostProcessor 调用和执行BFPP。
这里不得不提一个非常重要的BFPP ConfigurationClassPostProcessor 这个类对如下注解处理
①@PropertySource
②@CompontScan
③@Import
④@Bean
⑤@ImportResource
不管怎么说 对于这些注解修饰的类、又会把新的beanDefinition加入到Spring容器中。
- registerBeanPostProcessors注册BPP、实例和初始化BPP到Spring容器。方便后续对Bean的实例化后进行before和after方法。
- finishBeanFactoryInitialization。完成对象的创建工作。这个是创建Bean对象最核心方法
①合并bean的定义信息。即第一放到容器中的GenericBeanDefinition合并成RootBeanDefinition.
②遍历RootBeanDefinition集合、通过getBean -> doGetBean流程中getSingleton方法尝试从一、二、三缓存中获取Bean对象。
③ 如果缓存中不存在Bean对象,那么通过createBean -> doCreateBean的流程常见Bean对象。具体的流程如下: