Spring注解 生命周期
- bean的生命周期:bean创建–>初始化–>销毁的过程
- 在Spring中由容器管理bean的生命周期,我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的是或来调用我们自己定义的初始化和销毁方法
初始化和销毁调用时机
生命周期:
- 构造(对象创建)
单实例:在容器启动的时候创建
多实例:在每次获取的时候创建 - BeanPostProcessor.postProcessBeforeInitialization
- 初始化
对象创建完成并赋值好,调用初始化方法 - BeanPostProcessor.postProcessAfterInitialization
- 销毁
单实例:容器关闭的时候
多实例:容器不会管理这个bean,容器不会调用销毁方法
- 自定义初始化和销毁方法的方式:
- @Bean指定初始化和销毁方法
- 实现initializingBean和DisposableBean接口
- @PostConstruct 和@PreDestroy
- BeanPostProcessor 后置处理器
在初始化前后
自定义初始化和销毁的方式
@Bean指定初始化和销毁方法
第一种方式是通过@Bean指定初始化和销毁方法
@Bean(initMethod = "init",destroyMethod = "destroy")
@Bean 有两个属性:
- initMethod = “init” 指定初始化方法名为init(在要创建的类中的方法)
- destroyMethod = “destroy” 指定销毁方法名为destroy
这两个属性就等价于xml里Bean标签的init-method属性和destroy-method属性
单实例情况的输出:
initializingBean和DisposableBean接口
我们可以通过让Bean实现initializingBean接口定义初始化,的afterPropertiesSet()方法会在bean创建完成并属性赋值好后调用
让Bean实现DisposableBean接口定义销毁,DisposableBean接口的destroy()方法会在容器关闭的时候调用
@PostConstruct 和@PreDestroy
JSR250规范定义了两个注解:
这两个注解都是标在方法上的
- @PostConstruct 在bean创建完成并且属性赋值完成,来执行初始化方法
- @PreDestroy 在容器销毁bean之前 会调用这个注解标注的方法
BeanPostProcessor 后置处理器
在bean初始化前后进行一些处理工作
- postProcessBeforeInitialization在bean创建后但初始化之前(例如initializingBean的afterPropertiesSet方法调用、initMethod指定的方法调用)
- postProcessAfterInitialization bean初始化之后调用
这两个方法的参数:
- bean就是容器中已经创建的对象(返回也返回这个对象)
- beanName就是对象的名字
BeanPostProcessor原理
populateBean()//1. 给属性赋值
{
//2. 后置处理器 调用PostProcessorsBeforeInitialization()方法
applyBeanPostProcessorsBeforeInitialization
//3. 调用自定义初始化方法
invokeInitMethods
//4. 后置处理器 调用PostProcessorsAfterInitialization()方法
applyBeanPostProcessorsAfterInitialization
}
-
在doCreateBean方法中
我们可以看到是先调populateBean()方法对bean的属性进行赋值,然后再调用initializeBean()方法 -
initializeBean()方法中
-
applyBeanPostProcessorsBeforeInitialization()方法
这个方法就是把所有的后置处理器都拿出来,然后调用每个的postProcessBeforeInitialization方法,如果有一个为null,就返回(后面的后置处理器就不调用了)
Spring底层对BeanPostProcessor的使用
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async 等都是用BeanPostProcessor完成的
BeanPostProcessor的实现类有很多,如下:
ApplicationContextAwareProcessor
其中ApplicationContextAwareProcessor 可以帮组件注入IOC容器
当我们想给组件注入IOC容器时,步骤:
- 我们需要实现ApplicationContextAware接口:
- setApplicationContext 方法就会把IOC容器传进来
我们在setApplicationContext方法中将传进来的applicationContext保存
上面这个功能就是ApplicationContextAwareProcessor做的.具体我们可以在Dog的setApplicationContext 方法处打一个断点,看到:
在Bean初始化之前,
ApplicationContextAwareProcessor的postProcessBeforeInitialization方法被调用
invokeAwareInterfaces 方法
把IOC 注入
传过来的IOC 容器:
BeanValidationPostProcessor
做数据校验的时候会用到BeanValidationPostProcessor
当对象创建完,给bean赋值后,还可以做数据校验
InitDestroyAnnotationBeanPostProcessor
处理@PostConstruct 和@PreDestroy 注解
postProcessBeforeInitialization 方法:
- 找到标注的生命周期注解:
- invokeInitMethods 执行注解对应的方法
当前遍历的element元素 对应的方法:
AutowiredAnnotationBeanPostProcessor
自动装配 @Autowire就是通过 AutowiredAnnotationBeanPostProcessor 在对象创建完后,处理autowire标注的所有属性 来进行注入值