Spring Bean 生命周期
说到Spring Bean的生命周期,有好多内容,大部分都用不到,除了几个关键点可以用到。以下图就描述了
上面的图就看看吧,我也不讲诉太多,就列举几个常见的,普通的流程吧。
在大部分情况下我们基本用的是适配器设计模式,就是一个class里面 调用其他其他class,并以属性形式注入存在。主要关注下初始化和销毁阶段的内容,
然后实现InitializingBean, DisposableBean,再然后写Bean 中的init-method和destroy-method,了解下其流程
我列举了一个Car,里面有个RedCar属性,来获取其名称。都是注解版
1 public class Car implements InitializingBean, DisposableBean 2 { 3 private String name; 4 private RedCar redCar; 5 6 public Car() 7 { 8 System.out.println("Car构造函数"); 9 } 10 11 public String getName() 12 { 13 return name; 14 } 15 16 @Value("China Car") 17 public void setName(String name) 18 { 19 System.out.println("Car设置属性"); 20 this.name = name; 21 } 22 23 public RedCar getRedCar() 24 { 25 return redCar; 26 } 27 28 @Autowired 29 public void setRedCar(RedCar redCar) 30 { 31 System.out.println("Car内的RedCar设置属性"); 32 this.redCar = redCar; 33 } 34 35 public void myInit() 36 { 37 System.out.println("Car调用<bean>的init-method属性指定的初始化方法"); 38 } 39 40 @Override 41 public void afterPropertiesSet() throws Exception 42 { 43 System.out.println("Car调用InitializingBean的afterPropertiesSet"); 44 } 45 46 @Override 47 public void destroy() throws Exception 48 { 49 System.out.println("Car调用DisposableBean的destroy"); 50 } 51 52 public void myDestroy() 53 { 54 System.out.println("Car调用<bean>的destroy-method属性指定的初始化方法"); 55 } 56 }
RedCar:
1 public class RedCar implements InitializingBean, DisposableBean 2 { 3 private String name; 4 5 public RedCar() 6 { 7 System.out.println("RedCar构造函数"); 8 } 9 10 public String getName() 11 { 12 return name; 13 } 14 15 @Value("China RedCar") 16 public void setName(String name) 17 { 18 System.out.println("RedCar设置属性"); 19 this.name = name; 20 } 21 22 @Override 23 public void afterPropertiesSet() throws Exception 24 { 25 System.out.println("RedCar调用InitializingBean的afterPropertiesSet"); 26 } 27 28 @Override 29 public void destroy() throws Exception 30 { 31 System.out.println("RedCar调用DisposableBean的destroy"); 32 } 33 34 public void myInit() 35 { 36 System.out.println("RedCar调用<bean>的init-method属性指定的初始化方法"); 37 } 38 39 public void myDestroy() 40 { 41 System.out.println("RedCar调用<bean>的destroy-method属性指定的初始化方法"); 42 } 43 }
其中@Autowired注解放在setxxx方法上,不要放在成员变量上,不然是不会执行setxxx的内容
然后写个Configuration注解注入Bean,并写上initMethod和destroyMethod方法
1 @Configuration 2 public class MyConfig 3 { 4 @Bean(initMethod = "myInit", destroyMethod = "myDestroy") 5 public Car getCar() 6 { 7 return new Car(); 8 } 9 10 @Bean(initMethod = "myInit", destroyMethod = "myDestroy") 11 public RedCar getRedCar() 12 { 13 return new RedCar(); 14 } 15 }
Main函数执行
1 public class Application 2 { 3 public static void main(String[] args) 4 { 5 AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class); 6 String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames(); 7 8 Car car = annotationConfigApplicationContext.getBean(Car.class); 9 annotationConfigApplicationContext.close(); 10 } 11 }
其中annotationConfigApplicationContext.close()是用来销毁Bean
运行结果如下
Car构造函数 Car设置属性 RedCar构造函数 RedCar设置属性 RedCar调用InitializingBean的afterPropertiesSet RedCar调用<bean>的init-method属性指定的初始化方法 Car内的RedCar设置属性 Car调用InitializingBean的afterPropertiesSet Car调用<bean>的init-method属性指定的初始化方法 Car调用DisposableBean的destroy Car调用<bean>的destroy-method属性指定的初始化方法 RedCar调用DisposableBean的destroy RedCar调用<bean>的destroy-method属性指定的初始化方法
总结:
1、先调用自己的无参数构造函数(你写个有参构造是没啥作用的)
2、再执行属性注入,就先调用属性类的构造函数
3、再注入属性类的属性
4、调用属性类的InitializingBean的afterPropertiesSet
5、调用属性类的init-method
6、再返回该类的属性setxxx
7、.....重复步骤
8、销毁的顺序要注意下,最后执行的属性类的销毁
然后Spring 又出现了一个后期处理加强的Bean处理 BeanPostProcessor 接口
这个BeanPostProcessor是针对所有的bean
代码如下:
1 @Component 2 public class MyPostProcessor implements BeanPostProcessor 3 { 4 @Override 5 public Object postProcessBeforeInitialization(Object o, String s) throws BeansException 6 { 7 System.out.println(String.format("BeanPostProcessor-postProcessBeforeInitialization:%s,%s", o, s)); 8 return o; 9 } 10 11 @Override 12 public Object postProcessAfterInitialization(Object o, String s) throws BeansException 13 { 14 System.out.println(String.format("BeanPostProcessor-postProcessAfterInitialization:%s,%s", o, s)); 15 return o; 16 } 17 }
运行如下:
Car构造函数 Car设置属性 RedCar构造函数 RedCar设置属性 BeanPostProcessor-postProcessBeforeInitialization:dto.RedCar@70b0b186,getRedCar RedCar调用InitializingBean的afterPropertiesSet RedCar调用<bean>的init-method属性指定的初始化方法 BeanPostProcessor-postProcessAfterInitialization:dto.RedCar@70b0b186,getRedCar Car内的RedCar设置属性 BeanPostProcessor-postProcessBeforeInitialization:dto.Car@ba8d91c,getCar Car调用InitializingBean的afterPropertiesSet Car调用<bean>的init-method属性指定的初始化方法 BeanPostProcessor-postProcessAfterInitialization:dto.Car@ba8d91c,getCar Car调用DisposableBean的destroy Car调用<bean>的destroy-method属性指定的初始化方法 RedCar调用DisposableBean的destroy RedCar调用<bean>的destroy-method属性指定的初始化方法
总结:
postProcessBeforeInitialization和postProcessAfterInitialization是在InitializingBean和init-method之前后执行的。
postProcessBeforeInitialization是前
postProcessAfterInitialization是后
其他的不说了,说多了记不住,最后一句话概括,bean的生命周期先自身构造再调用依赖后再回来执行自己,销毁顺序反向,先自己销毁再销毁依赖的,BeanPostProcessor就是在初始化中前后执行。