第一步:启动ApplicationContext
第二步:创建BeanFactory工厂
第三步:初始化BeanFactory
1、解析配置类,得到BeanDefinition,并注册到BeanFactory中
i. 解析@ComponentScan,此时就会完成扫描
ii. 解析@Import
iii. 解析@Bean
2、 因为ApplicationContext还支持国际化,所以还需要初始化MessageSource对象
3、 因为ApplicationContext还支持事件机制,所以还需要初始化ApplicationEventMulticaster对象
4、 把用户定义的ApplicationListener对象添加到ApplicationContext中,等Spring启动完了就要发布事件了
5、创建非懒加载的单例Bean对象,并存在BeanFactory的单例池中。
6、调用Lifecycle Bean的start()方法
7、发布ContextRefreshedEvent事件
第四步:执行BeanFactory后置处理器
Spring支持用户定义BeanFactoryPostProcessor的实现类Bean,来对BeanFactory进行加工。这一步是发生在Spring启动时,创建单例Bean之前的,所以此时对BeanDefinition就行修改是会生效的。
第五步:扫描
这一步是在第四步过程中进行的
Spring扫描底层流程:https://www.processon.com/view/link/61370ee60e3e7412ecd95d43
第六步:生成BeanDefinition
第七步:合并BeanDefinition
通过扫描得到所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefinition
第八步:加载类
BeanDefinition合并之后,就可以去创建Bean对象了,而创建Bean就必须实例化对象,而实例化就必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的createBean()方法中,一开始就会调用:Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载。
ClassUtils.getDefaultClassLoader()
1. 优先返回当前线程中的ClassLoader
2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器
第九步:实例化前
当前BeanDefinition对应的类成功加载后,就可以实例化对象了,但是在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。这个扩展点叫
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()。
第十步:实例化
1、Supplier创建对象
首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。得直接使用BeanDefinition对象来设置Supplier。
2、工厂方法创建对象5.2 工厂方法创建对象
如果没有设置Supplier,则检查BeanDefinition中是否设置了factoryMethod,也就是工厂方法,Spring发现当前BeanDefinition方法设置了工厂方法后,就会区分这两种方式,然后调用工厂方法得到对象。
3、推断构造方法
Spring在基于某个类生成Bean的过程中,需要利用该类的构造方法来实例化得到一个对象,但是如果一个类存在多个构造方法,Spring会使用哪个呢?
Spring的判断逻辑如下:
- 如果一个类只存在一个构造方法,不管该构造方法是无参构造方法,还是有参构造方法,Spring都会用这个构造方法
2. 如果一个类存在多个构造方法
a. 这些构造方法中,存在一个无参的构造方法,那么Spring就会用
这个无参的构造方法
b. 这些构造方法中,不存在一个无参的构造方法,那么Spring就会
报错
Spring的设计思想是这样的:
1. 如果一个类只有一个构造方法,那么没得选择,只能用这个构造方法
2. 如果一个类存在多个构造方法,Spring不知道如何选择,就会看是否有无参的构造方法,因为无参构造方法本身表示了一种默认的意义
第十一步:BeanDefinition后置处理
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的 BeanDefinition进行加工
第十二步:实例化后
在处理完BeanDefinition后,Spring又设计了一个扩展点:
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()对实例化的Bean进行处理
第十三步:自动注入
填充属性
依赖注入底层原理流程图: https://www.processon.com/view/link/5f899fa5f346fb06e1d8f570
第十四步:执行Aware
完成了属性赋值之后,Spring会执行一些回调,包括:
1. BeanNameAware:回传beanName给bean对象。
2. BeanClassLoaderAware:回传classLoader给bean对象。
3. BeanFactoryAware:回传beanFactory给对象。
第十五步:初始化前
初始化前,也是Spring提供的一个扩展点:
BeanPostProcessor.postProcessBeforeInitialization()
利用初始化前,可以对进行了依赖注入的Bean进行处理。
第十六步:初始化
1. 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
2. 执行BeanDefinition中指定的初始化方法
第十七步:初始化后
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:
BeanPostProcessor.postProcessAfterInitialization()
可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。