Bean的生命周期
- 实例化Bean(通过BeanDefination反射调用无参构造方法创建实例,如果没有,则需要在构造方法上添加@Autowird)
- 给bean的属性set赋值
- 检查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);
- 执行BeanPostProcessor(Bean后处理器)的before方法,此时返回的Bean可以被偷梁换柱
- “偷梁换柱” = 在
postProcessBeforeInitialization里用一个新对象替换原 Bean - 主要用途:
- AOP 代理(Spring 里所有基于代理的增强其实就是这么干的)
- 装饰模式增强 Bean
- 做一些动态替换/包装
- “偷梁换柱” = 在
- 检查Bean是否实现了InitializingBean接口,如果实现了,那就执行里面的afterPropertiesSet()方法
- 初始化Bean, —- 配置文件中的init-method方法或者注解的@Bean(initMethod=”init”) (两者其一)
- 执行BeanProcessor的after方法,此时返回的Bean可以被偷梁换柱,AOP此时在这杯发现
- 使用Bean
- 销毁Bean,检查Bean是否实现了DisposableBean接口,实现的话执行里面的destroy方法
- 销毁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完成初始化后进行最终的处理,如代理增强或其他后处理逻辑。