Spring的Bean的生命週期方法執行順序測試

經過一個簡單的Maven工程來演示Spring的Bean生命週期函數的執行順序.java

下面是工程的目錄結構:spring

 

直接貼代碼:apache

 

pom.xml文件內容:maven

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>com.xuebusi</groupId>
 8     <artifactId>spring-test</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10 
11     <dependencies>
12         <dependency>
13             <groupId>org.springframework</groupId>
14             <artifactId>spring-context</artifactId>
15             <version>4.3.12.RELEASE</version>
16         </dependency>
17 
18         <dependency>
19             <groupId>junit</groupId>
20             <artifactId>junit</artifactId>
21             <version>4.12</version>
22             <scope>test</scope>
23         </dependency>
24     </dependencies>
25 
26 </project>

 

beans.xml配置文件:ide

該配置文件主要用於演示init-method和destory-method兩個方法的執行時機.函數

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:context="http://www.springframework.org/schema/context"
5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
6 
7     <context:component-scan base-package="com.xuebusi"></context:component-scan>
8     <bean id="userService" class="com.xuebusi.service.UserService" init-method="init" destroy-method="destory"/>
9 </beans>

 

SpringBeanPostProcessor類:post

這個類繼承了InstantiationAwareBeanPostProcessorAdapter類,重寫了它的一些和Bean的實例化以及初始化有關的生命週期方法.測試

可是這些方法是針對Spring容器中的全部Bean的,因此加了個if判斷,由於這裏只是演示userService這個Bean的生命週期.this

 1 import org.springframework.beans.BeansException;
 2 import org.springframework.beans.PropertyValues;
 3 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
 4 import org.springframework.stereotype.Component;
 5 
 6 import java.beans.PropertyDescriptor;
 7 
 8 @Component
 9 public class SpringBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
10 
11     @Override
12     public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
13         if ("userService".equals(beanName)) {
14             System.out.println(">>>> postProcessBeforeInstantiation");
15         }
16         return super.postProcessBeforeInstantiation(beanClass, beanName);
17     }
18 
19     @Override
20     public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
21         if ("userService".equals(beanName)) {
22             System.out.println(">>>> postProcessAfterInstantiation");
23         }
24         return super.postProcessAfterInstantiation(bean, beanName);
25     }
26 
27     @Override
28     public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
29         if ("userService".equals(beanName)) {
30             System.out.println(">>>> postProcessPropertyValues");
31         }
32         return super.postProcessPropertyValues(pvs, pds, bean, beanName);
33     }
34 
35     @Override
36     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
37         if ("userService".equals(beanName)) {
38             System.out.println(">>>> postProcessBeforeInitialization");
39         }
40         return super.postProcessBeforeInitialization(bean, beanName);
41     }
42 
43     @Override
44     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
45         if ("userService".equals(beanName)) {
46             System.out.println(">>>> postProcessAfterInitialization");
47         }
48         return super.postProcessAfterInitialization(bean, beanName);
49     }
50 }

 

UserService類:spa

這就是要演示的Bean,讓它實現Spring的InitializingBean接口來測試afterPropertiesSet方法, 實現BeanNameAware接口來測試setBeanName方法,實現BeanFactoryAware接口來測試setBeanFactory方法.

 1 import org.springframework.beans.BeansException;
 2 import org.springframework.beans.factory.BeanFactory;
 3 import org.springframework.beans.factory.BeanFactoryAware;
 4 import org.springframework.beans.factory.BeanNameAware;
 5 import org.springframework.beans.factory.InitializingBean;
 6 import org.springframework.stereotype.Service;
 7 
 8 import javax.annotation.PostConstruct;
 9 import javax.annotation.PreDestroy;
10 
11 @Service
12 public class UserService implements InitializingBean, BeanNameAware, BeanFactoryAware {
13 
14     private String userName;
15 
16     public UserService() {
17         System.out.println(">>>> UserService");
18     }
19 
20     public String getUserName() {
21         return userName;
22     }
23 
24     public void setUserName(String userName) {
25         this.userName = userName;
26     }
27 
28     @PostConstruct
29     public void postConstruct() {
30         System.out.println(">>>> postConstruct");
31     }
32 
33     @PreDestroy
34     public void preDestroy() {
35         System.out.println(">>>> preDestroy");
36     }
37 
38     public void init() {
39         System.out.println(">>>> init");
40     }
41 
42     public void destory() {
43         System.out.println(">>>> destory");
44     }
45 
46     public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
47         System.out.println(">>>> setBeanFactory");
48     }
49 
50     public void setBeanName(String s) {
51         System.out.println(">>>> setBeanName");
52     }
53 
54     public void afterPropertiesSet() throws Exception {
55         System.out.println(">>>> afterPropertiesSet");
56     }
57 }

 

AppTest類:

該類經過junit測試方法來啓動一個Spring容器,並從容器中獲取userService這個Bean對象.最後調用close方法銷燬Spring容器.

 1 import com.xuebusi.service.UserService;
 2 import org.junit.Test;
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 
 5 public class AppTest {
 6 
 7     @Test
 8     public void run() {
 9         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
10         UserService userService = context.getBean("userService", UserService.class);
11         userService.setUserName("蒼井空");
12         String userName = userService.getUserName();
13         System.out.println(userName);
14         context.close();
15     }
16 }

 

 運行AppTest的測試方法run()而後觀察控制檯,日誌展現出了"userService"這個Bean的生命週期函數執行順序:

 1 >>>> postProcessBeforeInstantiation
 2 >>>> UserService
 3 >>>> postProcessAfterInstantiation
 4 >>>> postProcessPropertyValues
 5 >>>> setBeanName
 6 >>>> setBeanFactory
 7 >>>> postProcessBeforeInitialization
 8 >>>> postConstruct
 9 >>>> afterPropertiesSet
10 >>>> init
11 >>>> postProcessAfterInitialization
12 蒼井空
13 >>>> preDestroy
14 >>>> destory

 

總結一個Bean的生命週期方法執行順序:

1. 實例化前                postProcessBeforeInstantiation()
2. 構造方法                構造方法
3. 實例化後                postProcessAfterInstantiation()
4. 設置屬性                postProcessProperties()
5. 設置Bean名稱            setBeanName()
6. 設置BeanFactory        setBeanFactory()
7. 初始化前                postProcessBeforeInitialization()
8. 構造以後                加了 @PostConstruct 的方法
9. 全部屬性賦值以後         afterPropertiesSet()
10.初始化方法              配置文件中指定的 init-method 方法
10.初始化後                postProcessAfterInitialization()
11.銷燬以前                加了 @PreDestroy 的方法
12.銷燬方法                配置文件中指定的 destroy-method 方法
相關文章
相關標籤/搜索