Spring的Bean的生命周期方法执行顺序测试

通过一个简单的Maven工程来演示Spring的Bean生命周期函数的执行顺序.

下面是工程的目录结构:

 

直接贴代码:

 

pom.xml文件内容:

 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配置文件:

该配置文件主要用于演示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类:

这个类继承了InstantiationAwareBeanPostProcessorAdapter类,重写了它的一些和Bean的实例化以及初始化有关的生命周期方法.

但是这些方法是针对Spring容器中的所有Bean的,所以加了个if判断,因为这里只是演示userService这个Bean的生命周期.

 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类:

这就是要演示的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 方法

 

posted @ 2019-05-19 12:12  xuebusi  阅读(1467)  评论(0编辑  收藏  举报