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

   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.观察运行结果

5.结论

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

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

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

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

原文地址:https://www.cnblogs.com/shunyang/p/4477202.html