Bean 的生命周期

108 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

Bean 的生命周期

在前文中,我们介绍过如何借助BeanFactoryPostProcessor 来干预Bean 的容器启动阶段(第一阶段),那么接下来我们来介绍bean 的实例化阶段是如何实现的(第二阶段)。

根据之前的分析,我们知道,在容器启动之后,系统并不会立刻就去实例化相对应的bean 的定义。在容器启动之后,容器仅仅包含了所有对象的BeanDefinition,而BeanDefinition 的作用就是用来保存bean 实例化阶段所需要的基本信息的。

在请求方通过BeanFactory 的getBean() 方法来请求获取某个对象的实例的时候,才有可能触发到Bean 的实例化过程。

对于BeanFactory 的getBean() 方法,可以被显式调用,也可以在容器内部被隐式调用。

隐式调用有以下两种情况:

  1. 对于BeanFactory,对象的实例化默认采用“延迟初始化”。当请求方获取某个对象的时候,如果这个对象依赖了其他对象,那么容器首先实例化其依赖的所有对象,然后再实例化这个对象。这种情况下,是在容器内部以隐式方式调用getBean() 方法的。
  2. 对于ApplicationContext,在容器启动的时候就会实例化所有的bean。但是在ApplicationContext 内部依旧遵循着Spring 容器实现流程的两个阶段。但是它与BeanFactory 的区别就是在容器启动完成之后,会紧接着调用注册到容器中的所有bean 的实例化方法getBean()。

而在上文之所以说“可能”触发Bean 的实例化阶段过程,是因为只有在某个bean 的getBean() 方法在被第一次调用的时候才会触发。(不论是显示调用还是隐式调用)

在第二次调用getBean() 方法的时候,则会直接返回容器中缓存的第一次调用方法得到的实例化的实例。(对于prototype 类型的bean 除外)

这个时候,如果在调用getBean() 方法之后发现这个bean 还没有被实例化,那么Spring 就会通过createBean() 方法来对这个对象进行实例化操作。过程如图所示:

image.png

在Spring 中,容器会对其管理的所有对象都给予统一的生命周期管理,这些对象不会像之前那样“new 完了被使用之后,脱离了作用域就被回收”的命运。