前言
对于Spring开发者来说,了解Bean的生命周期流程是非常重要的,可以帮助我们更好地理解Spring容器的运作机制,并且在实际开发中更加灵活地利用Bean的生命周期来完成各种定制化的需求。
Spring Bean的生命周期指的是Bean从创建到初始化再到销毁的过程,这个过程是由IOC容器管理。
当一个 Bean 被加载到 Spring 容器时,它就具有了生命,而 Spring 容器在保证一个 Bean 能够使用之前,会进行很多工作。
在Spring容器中,Bean的生命周期经历了多个阶段,包括实例化、依赖注入、Aware接口处理、后置处理器、初始化、销毁等过程。这些过程也为我们提供了很多扩展和定制的机会,比如可以通过实现InitializingBean接口或者自定义init-method标签来定义初始化方法,通过实现DisposableBean接口或者自定义destroy-method标签来定义销毁方法。下面我们来对各个阶段进行介绍:
详解
Bean 的生命周期概括起来就是 4 个阶段:
- 实例化(Instantiation)
- 属性赋值(Populate)
- 初始化(Initialization)
- 销毁(Destruction)
但要细分的话可以说是7个阶段
首先会通过一个非常重要的类,叫做BeanDefinition获取bean的定义信息,这里面就封装了bean的所有信息。
BeanDefinition 是 Spring 框架中用来描述 Bean 的元数据对象,这个元数据包含了关于 Bean 的一些基本信息,包括以下几个方面:
- Bean 的类信息: 这是 Bean 的全限定类名,即这个 Bean 实例化后的具体类型。
- Bean 的属性信息: 包括了如 Bean 的作用域(是单例还是原型)、是否为主要的 Bean(primary)、描述信息等。
- Bean 的行为特性: 例如 Bean 是否支持延迟加载,是否可以作为自动装配的候选者,以及 Bean 的初始化和销毁方法等。
- Bean 与其他 Bean 的关系: 比如说这个 Bean 所依赖的其他 Bean,以及这个 Bean 是否有父 Bean。
- Bean 的配置信息: 这包括了 Bean 的构造器参数,以及属性值等。
BeanDefinitionReader
可以将XML、注解等形式的bean配置信息解析读取进来,将其转换为 IoC 容器内部的数据结构:BeanDefinition
第一步是调用构造函数实例化bean
根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean
第二步是bean的依赖注入,比如一些set方法注入,像平时开发用的@Autowire都是这一步完成
第三步是处理Aware接口,如果某一个bean实现了Aware接口就会重写方法执行
aware接口是感知的意思,实现该接口的bean,可以访问并获取spring容器中对应前缀的对象实例。这些Aware系列接口增强了Spring bean的功能,但是也会造成对Spring框架的绑定,增大了与Spring框架的耦合度。(Aware是“意识到的,察觉到的”的意思,实现了Aware系列接口表明:可以意识到、可以察觉到)
- 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
- 如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
- 如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
第四步是bean的后置处理器BeanPostProcessor,这个是前置处理器
如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
第五步是初始化方法,比如实现了接口InitializingBean或者自定义了方法init-method标签或@PostContruct
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
spring初始化bean有两种方式:
- 第一:实现InitializingBean接口,继而实现afterPropertiesSet的方法
- 第二:反射原理,配置文件使用init-method标签直接注入bean
第六步是执行了bean的后置处理器BeanPostProcessor,主要是对bean进行增强,有可能在这里产生代理对象
如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
最后一步是销毁bean