Spring Bean的生命周期(强烈推荐)

对于普通的Java对象,当new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收。而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制。

普通Java对象和Spring所管理的Bean的区别

  • 首先要知道的是普通Java对象和Spring所管理的Bean实例化的过程是有些区别的在普通Java环境下创建对象简要的步骤可以分为:

    1. java源码被编译为被编译为class文件
    2. 等到类需要被初始化时(比如说new反射等)
    3. class文件被虚拟机通过类加载器加载到JVM
    4. 初始化对象供我们使用
  • 简单来说,可以理解为它是用Class对象作为「模板」进而创建出具体的实例
    Spring所管理的Bean不同的是,除了Class对象之外,还会使用BeanDefinition的实例来描述对象的信息

  • 比如说: 我们可以在Spring所管理的Bean有一系列的描述:@Scope@Lazy@DependsOn 等等

  • 可以理解为:Class只描述了类的信息,而BeanDefinition描述了对象的信息

BeanDefinition定义SpringBean的类信息

  • Spring在启动的时候需要「扫描」在XML / 注解 / JavaConfig 中需要被Spring管理的Bean信息
  • 随后,会将这些信息封装成BeanDefinition,最后会把这些信息放到一个beanDefinitionMap

扫描 -> 收集至BeandefinitionMap

  • 接着会遍历这个beanDefinitionMap,执行BeanFactoryPostProcessor这个Bean工厂后置处理器的逻辑
    这里我们也可以自定义BeanFactoryPostProcessor来对我们定义好的Bean元数据进行获取或者修改

BeanFactoryPostProcessor处理器执行完了以后,就到了实例化对象了,下面这张图是Bean的整个生命周期:

在这里插入图片描述

1、实例化Bean

  • 在Spring里面是通过反射机制来实现的,一般情况下会通过反射选择合适的构造器来把对象实例化,这里把对象实例化,只是把对象给创建出来,而对象具体的属性是还没注入的。

2、注入对象属性(populateBean)

  • 实例化后的对象被封装BeanWrapper对象中。紧接着,Spring根据BeanDefinition中的信息进行依赖注入。并且通过BeanWrapper提供的设置属性的接口完成依赖注入。

  • 提示:在这一步涉及到了循环依赖问题(三级缓存:Bean对象在实例化后会放入第三级缓存singletonFactories(key: beanName,value: objectFactory)

相关属性注入完之后,往下接着就是初始化的工作了

3、检查Aware相关接口并设置相关依赖

  • 首先判断该Bean是否实现了Aware相关的接口,如果存在则填充相关的资源
    比如我希望通过代码程序的方式去获取指定的 Spring Bean 我们这边会抽取成一个工具类,去实现ApplicationContextAware接口,来获取ApplicationContext对象进而获取Spring Bean

Aware相关的接口处理完之后,就会到BeanPostProcessor了

4、BeanPostProcessor(后置处理器)

  • BeanPostProcessor这个接口有两个方法,一个是before,一个是after
  • 所以,执行完Aware相关的接口就会执行BeanPostProcessor里面的的before方法

BeanPostProcessor相关方法before执行完了后就会执行 init 相关的方法

5、InitializingBean与init-method

  • init 相关方法: @PostConstruct、实现了InitializingBean接口、定义的init-method方法
  • InitializingBean接口里只有一个方法afterPropertiesSet()
  • 这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。
    在这里插入图片描述
  • 当时我还去官网去看他们的被调用执行顺序分别是:@PostConstruct、实现了InitializingBean接口以及init-method方法

init方法执行完之后,就会执行BeanPostProcessor的after方法也就是后置处理器

6、BeanPostProcessor(后置处理器)

  • 这个BeanPostProcessor后置处理器是AOP实现的关键(关键子类AnnotationAwareAspectJAutoProxyCreator
  • 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。SpringAOP就是在这里实现的

7、基本重要的流程已经走完了,我们就可以获取到对象去使用了

8、最后就是销毁,销毁的时候就看有没有配置相关的destroy方法,执行就完事了


我稍微总结一下今天的内容吧

  • 首先是Spring Bean的生命周期过程,Spring使用BeanDefinition来装载着我们给Bean定义的元数据

  • 实例化Bean的时候实际上就是遍历BeanDefinitionMap

  • Spring的Bean实例化和属性赋值是分开两步来做的

  • 在Spring Bean的生命周期,Spring预留了很多的hook给我们去扩展

    1. Bean实例化之前有BeanFactoryPostProcessor
    2. Bean实例化之后,初始化时,有相关的Aware接口供我们去拿到Context相关信息
    3. 环绕着初始化阶段,有BeanPostProcessor(AOP的关键)
    4. 在初始化阶段,有各种的init方法供我们去自定义
  • 而循环依赖的解决主要通过三级的缓存

  • 在实例化后,会把自己扔到三级缓存(此时的key是BeanName,Value是ObjectFactory)

  • 在注入属性时,发现**A**需要依赖B,也会走B的实例化过程,B属性注入依赖A,从三级缓存找到A,删掉三级缓存,放到二级缓存

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值