IOC容器的初始化最简单的也就是3个步骤,初始化Spring容器,注册内置的BeanPostProcessor的BeanDefinition到容器中;将配置类的BeanDefinition注册到容器中;调用refresh()方法刷新容器
结合AnnotationConfigApplicationContext 进行分析
初始化容器,注册后置处理器的BeanDefinition
1.实例化容器
容器就是来创建管理bean的,所以必须先实例化BeanFactory【DefaultListableBeanFactory】工厂,用来生成Bean对象;
接下来就要对Bean进行处理,首先得先找到需要加载的Bean
2.配置处理Bean的后置处理器
因为AnnotationConfigApplicationContext 这个容器是基于注解的,所以要实例化BeanDefinitionReaderBean定义读取器,用于对特定注解(如@Service、@Repository)的类进行读取转化成 BeanDefinition 对象,其中最重要的组件就是 ConfigurationClassPostProcessor 和 AutowiredAnnotationBeanPostProcessor ,前者是一个 beanFactory 后置处理器,用来完成 bean 的扫描与注入工作,后者是一个 bean 后置处理器,用来完成 @AutoWired 自动注入;对于BeanDefinition,就是存储一些Bean的定义信息的,比如是否懒加载,是否单例等。
3.配置路径扫描,查找Bean对象
Bean的后置处理器加载完成,需要开始进行扫描Bean了,实例化ClassPathBeanDefinitionScanner路径扫描器,用于对指定的包目录进行扫描查找 bean 对象。
注册配置类的BeanDefinition
后置处理器注册完成后就需要对配置类进行注册
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean:来解析用户传入的 Spring 配置类,解析成一个 BeanDefinition 然后注册到容器中
刷新容器refresh()
都注册完成后,就来到了Spring中最重要的一块,就是refresh()
只要是在spring中的容器都会调用这个方法完成初始化。
这个方法可以分为12个步骤
- prepareRefresh();对容器进行预处理,初始化一些设置,校验合法性,保存早期事件
- 是obtainFreshBeanFactory();获取需要创建的beanFactory并设置序列化ID
- 是prepareBeanFactory(beanFactory);Bean工厂的预处理,就是添加Beanfactory所需要的组件,类加载器,BPP等
- 是postProcessBeanFactory(beanFactory);子类重写该方法后,可以实现在BeanFactory创建并预处理完成以后做进一步的设置
- 是invokeBeanFactoryPostProcessors(beanFactory):调用Beanfactory的后置处理器,在此后置处理器中可以对BeanDefinition进行重定义
- registerBeanPostProcessors(beanFactory);注册BPP,这是最个比较重要的后置处理器,用来干预Spring初始化bean的流程,从而完成代理、自动注入、循环依赖等功能
- initMessageSource();初始化MessageSource组件,主要用于做国际化功能,消息绑定与消息解析:
- initApplicationEventMulticaster():初始化事件派发器,在注册监听器时会用到
- onRefresh():留给子容器、子类重写这个方法,在容器刷新的时候可以自定义逻辑
- registerListeners():注册监听器:将容器中所有的ApplicationListener注册到事件派发器中,并派发之前步骤产生的事件
- finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例bean,核心方法是preInstantiateSingletons(),会调用getBean()方法创建对象,比较重要
- finishRefresh():发布BeanFactory容器刷新完成事件:
其中最重要的3步是
invokeBeanFactoryPostProcessors,调用beanfactory的后置处理器
registerBeanPostProcessors(beanFactory),注册Bean的后置处理器
finishBeanFactoryInitialization(beanFactory),完成Bean工厂的初始化
这3个方法就要结合Bena的生命周期来说了
BeanDefinition–>WrapperBean–>Bean
刚说了,在容器的创建阶段,有一个BeanDefinitionReader,会将Dean的元信息转换成BeanDefinition,然后调用BeanDefinationRegistry中的doRegisterBean方法将BeanDefinition注册到BeanDefinationRegistry(BeanDefination登记处),它是一种以键值对形式,通过特定的Bean定义的id,映射到相应的BeanDefination。
说到这,就要说道refresh()中最重要的3个步骤了
- invokeBeanFactoryPostProcessors
他会调用beanfactory的后置处理器,BeanFactoryPostProcessors是容器启动阶段Spring提供的一个扩展点,主要负责对注册到BeanDefinationRegistry中的一个个的BeanDefination进行一定程度上的修改与替换。 - registerBeanPostProcessors
BPP是Spring中提供的第二个扩展点,在属性设置之前修改bean的属性 - finishBeanFactoryInitialization
在这里将会彻底完成Bean的初始化
这个方法会调用preInstantiateSingletons();然后调用applicationContext.getBean(“name”);这个方法是个空方法,需要调用父类的AbstractApplicationContext.getBean(“beanName”),然后调用AbstractBeanFactory类下面的doGetBean()方法,这个才是真正的创建Bean对象
doGetBean
进入doGetBean后,会先调用getSingleton(beanName)去单例池中尝试获取,拿不到去缓存池中哪,再拿不到就返回空,在这会进行一个判断,判断这个Bean是不是正在创建,如果不是返回空,然后会有第二次的getSingleton(beanName,singletonFactory),添加到beforeSingletonCreation(beanName);表示这个Bean正在创建,然后执行creatBean,在doGetBean和creatBean中会用到多个后置处理器来完成Bean的创建。
后置处理器
-
CreateBean–resolveBeforeInstantiation–InstantiationAwareBeanPostProcessor–postProcessBeforeInstantiation
这个方法会找出来创建这个Bean所需要的所有后置处理器,如果需要代理,则会返回一个代理对象 -
doCreateBean–createBeanInstance–determineConstructorsFromBeanPostProcessors–SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
determineCandidateConstructors这个方法会按照规则区寻找构造方法,若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB 增强 bean 实例。
通过工厂方法创建 bean 实例
通过构造方法自动注入(autowire by constructor)的方式创建 bean实例,如果使用构造方法,则会会返回匹配度最高的一个构造方法
通过无参构造方法方法创建 bean 实例
createBeanInstance将会返回实例化后的对象
-
doCreateBean–applyMergedBeanDefinitionPostProcessors–MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
在这里Spring可以扫描每个类中那些属性需要自动注入,postProcessMergedBeanDefinition是一个接口,要找实现类中的方法。 -
doCreateBean-getEarlyBeanReference—SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
来解决循环引用 -
doCreateBean-populateBean—InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
最后一次机会在属性注入前修改Bean的属性值,具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回 -
doCreateBean-populateBean–InstantiationAwareBeanPostProcessor.postProcessProperties
这里会进行 @Autowired 和 @Resource 等的注入工作 -
doCreateBean-initializeBean–BeanPostProcessor.postProcessBeforeInitialization在这会处理重写的init方法回调
-
doCreateBean-initializeBean–BeanPostProcessor.postProcessAfterInitialization执行AOP
BeanPostProcessor是对Ioc的扩展,在这个BeanPostProcessor.postProcessAfterInitialization方法中完成AOP
总结一下
Bean的生命周期过程被上述的8个后置处理器贯穿
简单总结下CreateBean–doCreateBean
找出需要的后置处理器,判断是否代理,如果不代理则进行,则进行创建
从给出的构造方法中找出最匹配的进行实例化,实例化后找出需要注入的属性
然后判断是否有循环引用问题
然后再给次机会,判断是否需要属性注入,不注入的话直接返回,需要注入的化就直接注入
注入完成后执行初始化方法,在初始化的时候会进行BPP扩展,并判断是否需要执行init-method,AOP也是在这里进行实现的,然后注册到disposableBeans