Bean的生命周期
1.实例化Bean(通过BeanDefinition反射调用无参构造创建对象,如果没有无参构造,需要指定唯一构造方法)
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);
4.执行BeanPostProcessor(Bean后处理器)的before方法
5.检查Bean是否实现了InitializingBean接口,实现的话执行里面的afterPropertiesSet()方法
6.初始化Bean——配置文件中的init-method方法或者方法注解上的@Bean(initMethod = "init")(二者其一,看使用配置文件还是注解)
7.执行BeanPostProcessor(Bean后处理器)的after方法
8.使用Bean
9.销毁Bean——检查Bean是否实现了DisposableBean接口,实现的话执行里面的destroy方法
10.销毁Bean——配置文件中的destroy-method方法或者方法注解上的@Bean(destroyMethod = "destroyMethod")(二者其一,看使用配置文件还是注解)
注意点:
- 销毁Bean是在容器关闭前进行销毁
- 如果出现了@PostContruct和@PreDestroy(两个JDK注解,则会分别穿插在第四步和第八步之后)
大致分为五个阶段:
- 实例化:步骤一
- 依赖注入:步骤二
- 初始化:步骤三到七
- 使用:步骤八
- 销毁:步骤九到十
😃为什么初始化要有那么多步骤,每个步骤干了什么事?
灵活性:不同的步骤提供了不同的挂钩点,允许开发者在Bean的不同阶段插入自定义逻辑。
扩展性:通过实现不同的Aware接口或PostProcessor接口,开发者可以扩展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完成初始化后进行最终的处理,如代理增强或其他后处理逻辑。