三种不同实现初始化和销毁bean之前进行的操作的比较

时间:2021-01-18 19:41:00

   Spring容器中的bean是有生命周期的,Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作,常用的设定方式有以下三种:

  • 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;
  • 通过 <bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法;
  • 在指定方法上加上@PostConstruct 或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用。 

    这是我们就有个疑问,这三种方式是完全等同的吗,孰先孰后?

这里给大家做了一个测试

1.定义相关的实现类:

  1 package com.fdd;
2
3 import javax.annotation.PostConstruct;
4 import javax.annotation.PreDestroy;
5
6 import org.springframework.beans.factory.DisposableBean;
7 import org.springframework.beans.factory.InitializingBean;
8 /**
9 * 比较不同方式初始化、销毁bean的顺序
10 *2015年5月4日 下午5:53:07
11 *chenshunyang
12 */
13 public class InitSequenceService implements InitializingBean,DisposableBean{
14 /**
15 * 构造方法
16 */
17 public InitSequenceService(){
18 System.out.println("InitSequenceService:constructor:"+message);
19 }
20 /**
21 * 业务方法
22 *
23 * 2015年5月4日 下午8:11:16
24 * chenshunyang
25 */
26 public void sayHello(){
27 System.out.println("hello "+message);
28 }
29
30 /**
31 * 通过实现DisposableBean接口来实现销毁bean之前的操作
32 *2015年5月4日 下午8:11:41
33 * chenshunyang
34 */
35 public void destroy() throws Exception {
36 System.out.println("InitSequenceService:destroy:"+message);
37 }
38 /**
39 * 通过实现InitializingBean接口来初始化bean
40 *2015年5月4日 下午8:12:35
41 * chenshunyang
42 */
43 public void afterPropertiesSet() throws Exception {
44 System.out.println("InitSequenceService:afterPropertiesSet:"+message);
45
46 }
47
48 /**
49 * 通过使用@PostConstruct来实现初始化bean
50 *
51 * 2015年5月4日 下午8:12:54
52 * chenshunyang
53 */
54 @PostConstruct
55 public void postConstruct1() {
56 System.out.println("InitSequenceService: postConstruct1:"+message);
57 }
58
59 /**
60 * 通过使用@PreDestroy来实现销毁bean之前操作
61 *
62 * 2015年5月4日 下午8:13:15
63 * chenshunyang
64 */
65 @PreDestroy
66 public void preDestroy1(){
67 System.out.println("InitSequenceService: preDestroy1:"+message);
68 }
69
70 @PostConstruct
71 public void postConstruct2() {
72 System.out.println("InitSequenceService: postConstruct2:"+message);
73 }
74
75 @PreDestroy
76 public void preDestroy2(){
77 System.out.println("InitSequenceService: preDestroy2:"+message);
78 }
79 /**
80 * 通过在配置文件中指定init-method方法来初始化bean
81 *
82 * 2015年5月4日 下午8:13:57
83 * chenshunyang
84 */
85 public void initMethod(){
86 System.out.println("InitSequenceService: init-method:"+message);
87 }
88 /**
89 * 通过在配置文件中指定destroy-method来实现销毁bean之前操作
90 * 2015年5月4日 下午8:14:25
91 * chenshunyang
92 */
93 public void destroyMethod(){
94 System.out.println("InitSequenceService: destroy-method:"+message);
95 }
96
97 public String message;
98
99 public String getMessage() {
100 return message;
101 }
102
103 public void setMessage(String message) {
104 this.message = message;
105 }
106 }

2.定义配置文件

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:aop="http://www.springframework.org/schema/aop"
5 xmlns:context="http://www.springframework.org/schema/context"
6 xsi:schemaLocation="
7 http://www.springframework.org/schema/beans
8 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
9 http://www.springframework.org/schema/aop
10 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
11 http://www.springframework.org/schema/context
12 http://www.springframework.org/schema/context/spring-context-3.1.xsd">
13
14 <!-- spring 容器采用注解配置:扫描注解配置-->
15 <context:annotation-config />
16
17 <bean id="initSequenceService" class="com.fdd.InitSequenceService" init-method="initMethod" destroy-method="destroyMethod">
18 <property name="message" value="123"></property>
19 </bean>
20 </beans>

3.编写测试代码

 1 package com.fdd;
2
3 import org.springframework.context.support.AbstractApplicationContext;
4 import org.springframework.context.support.ClassPathXmlApplicationContext;
5
6 public class Test {
7
8 public static void main(String[] args) {
9 AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring-service.xml");
10 InitSequenceService initSequenceService =(InitSequenceService)context.getBean("initSequenceService");
11 initSequenceService.sayHello();
12 context.registerShutdownHook();
13
14 }
15
16 }

4.观察运行结果

 

三种不同实现初始化和销毁bean之前进行的操作的比较

5.结论

通过上述输出结果,三者的先后顺序也就一目了然了:

初始化bean:Constructor > @PostConstruct > InitializingBean > init-method

bean在销毁的过程中:@PreDestroy > DisposableBean > destroy-method

并且通过@PostConstruct进行初始化bean、@PreDestroy进行销毁bean之前的操作可以写明多个方法