对于普通的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的整个生命周期:

Spring创建对象的原则是什么_spring

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,删掉三级缓存,放到二级缓存