Bean的生命周期

  1. 实例化Bean(通过BeanDefination反射调用无参构造方法创建实例,如果没有,则需要在构造方法上添加@Autowird)
  2. 给bean的属性set赋值
  3. 检查Bean是否实现了Aware相关接口,实现的话就执行方法
    Aware接口:空接口,有子类接口,子类接口有方法,方法作用见名知意:

BeanNameAware:void setBeanName(String name);

BeanFactoryAware:void setBeanFactory(BeanFactory beanFactory) throws BeansException;

ApplicationContextAware: void setApplicationContext(ApplicationContext applicationContext);

BeanClassLoaderAware:void setBeanClassLoader(ClassLoader classLoader);

  1. 执行BeanPostProcessor(Bean后处理器)的before方法,此时返回的Bean可以被偷梁换柱
    • “偷梁换柱” = 在 postProcessBeforeInitialization 里用一个新对象替换原 Bean
    • 主要用途:
      • AOP 代理(Spring 里所有基于代理的增强其实就是这么干的)
      • 装饰模式增强 Bean
      • 做一些动态替换/包装
  2. 检查Bean是否实现了InitializingBean接口,如果实现了,那就执行里面的afterPropertiesSet()方法
  3. 初始化Bean, —- 配置文件中的init-method方法或者注解的@Bean(initMethod=”init”) (两者其一)
  4. 执行BeanProcessor的after方法,此时返回的Bean可以被偷梁换柱,AOP此时在这杯发现
  5. 使用Bean
  6. 销毁Bean,检查Bean是否实现了DisposableBean接口,实现的话执行里面的destroy方法
  7. 销毁Bean,配置文件中的destroy-method方法或者方法注解上的@Bean(destroyMethod = “destroyMethod”)(二者其一,看使用配置文件还是注解)

注意点:

  • 销毁Bean是在容器关闭前进行的销毁
    容器关闭 = Spring 应用停止/销毁时,Spring 容器会结束 Bean 的管理。
  • 如果出现了@PostContruct和@PreDestroy(两个JDK注解,则会分别穿插在第四步和第八步之后)

大致就是分为五个阶段

实例化:步骤一

依赖注入:步骤二

初始化:步骤三到七

使用:步骤八

销毁:步骤九到十

为什么初始化要有那么多步骤,每个步骤干了什么事?

灵活性:不同的步骤提供了不同的挂钩点,允许开发者在不同阶段进行介入

扩展性:通过实现不同的Aware和PostProcessor接口,开发者可以扩展Bean的功能,增强与容器的交互能力

分离关注点:每个步骤专注于特定的任务,使得初始化过程更加清晰和可维护。

安全:确保Bean在被使用前经过充分的验证和准备

BeanNameAware.setBeanName()

作用:将Bean的名称传递给Bean实例。

用途:在Bean中需要知道自身名称时使用,方便在运行时进行标识或日志记录。

BeanFactoryAware.setBeanFactory()

作用:将当前BeanFactory实例传递给Bean。

用途:允许Bean访问其创建工厂,从而可以调用工厂的其他Bean或获取配置信息。

ApplicationContextAware.setApplicationContext()

作用:将当前的ApplicationContext实例传递给Bean。

用途:使Bean可以与Spring的应用上下文进行交互,获取上下文中的资源或其他Bean。

BeanPostProcessor.postProcessBeforeInitialization()

作用:在Bean初始化之前执行自定义逻辑。

用途:允许在Bean的依赖注入完成后但初始化方法调用前,对Bean进行额外处理,如修改属性或包装Bean实例。

InitializingBean.afterPropertiesSet()

作用:在Bean属性设置完成后进行初始化。

用途:提供了一个在所有属性设置完成后执行初始化逻辑的机会,通常用于配置验证或初始化某些资源。

自定义init-method方法

作用:调用用户在配置中指定的初始化方法。

用途:允许开发者通过配置文件指定一个自定义的初始化方法,以执行特定的初始化逻辑。

BeanPostProcessor.postProcessAfterInitialization()

作用:在Bean初始化之后执行自定义逻辑。

用途:允许在Bean完成初始化后进行最终的处理,如代理增强或其他后处理逻辑。