Spring__IOC容器初始化,Bean的生命周期

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个步骤

  1. prepareRefresh();对容器进行预处理,初始化一些设置,校验合法性,保存早期事件
  2. 是obtainFreshBeanFactory();获取需要创建的beanFactory并设置序列化ID
  3. 是prepareBeanFactory(beanFactory);Bean工厂的预处理,就是添加Beanfactory所需要的组件,类加载器,BPP等
  4. 是postProcessBeanFactory(beanFactory);子类重写该方法后,可以实现在BeanFactory创建并预处理完成以后做进一步的设置
  5. 是invokeBeanFactoryPostProcessors(beanFactory):调用Beanfactory的后置处理器,在此后置处理器中可以对BeanDefinition进行重定义
  6. registerBeanPostProcessors(beanFactory);注册BPP,这是最个比较重要的后置处理器,用来干预Spring初始化bean的流程,从而完成代理、自动注入、循环依赖等功能
  7. initMessageSource();初始化MessageSource组件,主要用于做国际化功能,消息绑定与消息解析:
  8. initApplicationEventMulticaster():初始化事件派发器,在注册监听器时会用到
  9. onRefresh():留给子容器、子类重写这个方法,在容器刷新的时候可以自定义逻辑
  10. registerListeners():注册监听器:将容器中所有的ApplicationListener注册到事件派发器中,并派发之前步骤产生的事件
  11. finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例bean,核心方法是preInstantiateSingletons(),会调用getBean()方法创建对象,比较重要
  12. 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
容器初始化

Bean的创建

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值