Bean的生命周期是指Bean的创建、初始化、销毁的过程。Bean的生命周期是由Spring的Ioc容器进行管理的。
关于Bean的创建详细过程请看我之前的文章:Spring注入Bean的四种方式,看这一篇就够了
首先从Spring的角度去看对Bean的创建、初始化和销毁过程。
创建:对Bean的属性成员进行赋值、封装对象。
初始化:后置处理器执行(初始化方法前后进行处理)。
销毁:执行销毁方法,对单例Bean容器进行清理。多实例的bean,容器只负责初始化, 但不会管理bean, 容器关闭时不会调用销毁方法。
从面的三个过程中出现了初始化方法和销毁方法,这两个方法是可以自定义的。共有三种方法,分别结合代码熟悉一下。
1、通过@Bean注解指定。
Config配置类:指明initMethod和destroyMethod的值
...
//init和destroy分别是自定义的初始化和销毁方法
@Bean(initMethod="init", destroyMethod="destory")
public Bike bike(){
return new Bike();
}
...
Bike类:自定义方法与initMethod和destroyMethod的值相对应
public class Bike {
//构造器
public Bike(){
System.out.println("Bike constructor..............");
}
//初始化
public void init(){
System.out.println("Bike .....init.....");
}
//销毁
public void destory(){
System.out.println("Bike.....destory");
}
}
2、实现Spring提供的接口 InitializingBean, DisposableBean
从代码看需要实现这两个接口的两个方法:
//初始化(设置属性值之后)
void afterPropertiesSet() throws Exception;
//销毁
void destroy() throws Exception;
Bike类:需要使用@Component注解使之成为Spring组件
package com.csdn.asong.bean;
@Component
public class Bike implements InitializingBean, DisposableBean{
public Bike(){
System.out.println("Bike......constructor............");
}
//当我们bean销毁时,调用此方法
@Override
public void destroy() throws Exception {
System.out.println("Bike......destory......");
//logger.error
}
//当我们的bean属性赋值和初始化完成时调用
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bike.......afterPropertiesSet()...");
}
}
同时配置类要加ComponentScan注解,扫描当前类所在的包
@ComponentScan("com.csdn.asong")
3、实现JSR250规范,这个规范是Spring提供的,需要在初始化和销毁方法上添加@PostConstruct和@PreDestroy注解
package com.csdn.asong.bean;
@Component
public class Bike {
public Bike(){
System.out.println("Bike.....constructor........");
}
//创建完成,赋值后进行初始化
@PostConstruct
public void init(){
System.out.println("Bike.....@PostConstruct........");
}
//销毁
@PreDestroy
public void destory(){
System.out.println("Bike.....@PreDestroy......");
}
}
同时配置类要加ComponentScan注解,扫描当前类所在的包
除了以上自定义的初始化方法外,Spring提供了后置处理器(BeanPostProcessor接口)对初始化方法进行增强,并且会对每个 bean对象的初始化方法进行增强
public interface BeanPostProcessor {
//初始化方法之前执行
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//初始化方法之后执行
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
实现:同样需要@Component注解
package com.csdn.asong.bean;
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//返回一个的对象(传过来的对象)
//在初始化方法调用之前进行后置处理工作,
//什么时候调用它: init-method=init之前调用
System.out.println("postProcessBeforeInitialization...."+beanName+"..."+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization...."+beanName+"..."+bean);
return bean;
}
}
对于非懒加载单例Bean,测试一下构造器、初始化方法、销毁方法、后置处理器方法的执行过程。(多例Bean和懒加载单例Bean使用的时候创建,不做讨论)
测试类:
public class Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("IOC容器创建完成........");
app.close();
}
}
配置类:
@ComponentScan("com.csdn.asong.bean")
@Configuration
public class 、MainConfigOfLifeCycle {
@Bean(initMethod="init", destroyMethod="destory")
public Bike bike(){
return new Bike();
}
}
控制台输出:
...
Bike constructor..............
postProcessBeforeInitialization....bike...com.csdn.bean.bean.Bike@6193932a
Bike .....init.....
postProcessAfterInitialization....bike...com.csdn.bean.bean.Bike@6193932a
IOC容器创建完成........
Bike.....destory
...
可以看到执行过程为:构造器、后置处理器(前置方法)、初始化方法、后置处理器(后置方法)、销毁方法。
在初始化的过程中有一步骤是invokeAwareMethods(beanName, bean); 表示调用Aware方法。Aware是指感知,Bean可以实现Aware相关接口,并且对应的后置处理器会把相应的组件注入。例如:我的 Bike 需要获取对应的容器上下文,那么它需要实现ApplicationContextAware,要看一下相关Aware源码,是需要实setApplicationContext方法。
此时的Bike:
public class Bike implements ApplicationContextAware {
//Spring容器上下文。由相应后置处理器注入
private ApplicationContext applicationContext;
public Bike(){
System.out.println("Bike constructor..............");
}
public void init(){
System.out.println("Bike .....init.....");
}
public void destory(){
System.out.println("Bike.....destory");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
那么这样在初始化Bean的时候,Spring的后置处理器 ApplicationContextAwareProcessor 就会在初始化的时候(初始化方法前)把Spring容器上下文通过set方法注入到Bike。为什么是init方法之前?因为这个后置处理器是BeanPostProcessor接口的实现类,但只实现了postProcessBeforeInitialization这个方法。
BeanPostProcessor是一个非常强大的接口,贯穿整个容器,下次有空再结合代码聊一聊。