• 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 方法
  • 相关阅读:
    安装Redis
    IntelliJ IDEA 2016.1 创建Maven Java Web项目(图解)
    MongoDB入门
    Oracler的锁概念
    Oracle 数据类型
    《锋利的jQuery》随笔(一)
    IList<T>之 First【学习笔记之Linq】
    入驻新园子
    使用nodejs下载风景壁纸
    nodejs爬取博客园的博文
  • 原文地址:https://www.cnblogs.com/jun1019/p/10888756.html
Copyright © 2020-2023  润新知