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就是在初始化中前后执行。

posted @ 2020-01-21 10:28  归去如风  阅读(157)  评论(0编辑  收藏  举报