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

下面是工程的目录结构:

直接贴代码:

pom.xml文件内容:

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.xuebusi</groupId>
<artifactId>spring-test</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies> </project>

beans.xml配置文件:

该配置文件主要用于演示init-method和destory-method两个方法的执行时机.

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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"> <context:component-scan base-package="com.xuebusi"></context:component-scan>
<bean id="userService" class="com.xuebusi.service.UserService" init-method="init" destroy-method="destory"/>
</beans>

SpringBeanPostProcessor类:

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

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

 import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component; import java.beans.PropertyDescriptor; @Component
public class SpringBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { @Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println(">>>> postProcessBeforeInstantiation");
}
return super.postProcessBeforeInstantiation(beanClass, beanName);
} @Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println(">>>> postProcessAfterInstantiation");
}
return super.postProcessAfterInstantiation(bean, beanName);
} @Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println(">>>> postProcessPropertyValues");
}
return super.postProcessPropertyValues(pvs, pds, bean, beanName);
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println(">>>> postProcessBeforeInitialization");
}
return super.postProcessBeforeInitialization(bean, beanName);
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println(">>>> postProcessAfterInitialization");
}
return super.postProcessAfterInitialization(bean, beanName);
}
}

UserService类:

这就是要演示的Bean,让它实现Spring的InitializingBean接口来测试afterPropertiesSet方法, 实现BeanNameAware接口来测试setBeanName方法,实现BeanFactoryAware接口来测试setBeanFactory方法.

 import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; @Service
public class UserService implements InitializingBean, BeanNameAware, BeanFactoryAware { private String userName; public UserService() {
System.out.println(">>>> UserService");
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} @PostConstruct
public void postConstruct() {
System.out.println(">>>> postConstruct");
} @PreDestroy
public void preDestroy() {
System.out.println(">>>> preDestroy");
} public void init() {
System.out.println(">>>> init");
} public void destory() {
System.out.println(">>>> destory");
} public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println(">>>> setBeanFactory");
} public void setBeanName(String s) {
System.out.println(">>>> setBeanName");
} public void afterPropertiesSet() throws Exception {
System.out.println(">>>> afterPropertiesSet");
}
}

AppTest类:

该类通过junit测试方法来启动一个Spring容器,并从容器中获取userService这个Bean对象.最后调用close方法销毁Spring容器.

 import com.xuebusi.service.UserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class AppTest { @Test
public void run() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.setUserName("苍井空");
String userName = userService.getUserName();
System.out.println(userName);
context.close();
}
}

运行AppTest的测试方法run()然后观察控制台,日志展示出了"userService"这个Bean的生命周期函数执行顺序:

 >>>> postProcessBeforeInstantiation
>>>> UserService
>>>> postProcessAfterInstantiation
>>>> postProcessPropertyValues
>>>> setBeanName
>>>> setBeanFactory
>>>> postProcessBeforeInitialization
>>>> postConstruct
>>>> afterPropertiesSet
>>>> init
>>>> postProcessAfterInitialization
苍井空
>>>> preDestroy
>>>> destory

总结一个Bean的生命周期方法执行顺序:

. 实例化前                postProcessBeforeInstantiation()
. 构造方法 构造方法
. 实例化后 postProcessAfterInstantiation()
. 设置属性 postProcessProperties()
. 设置Bean名称 setBeanName()
. 设置BeanFactory setBeanFactory()
. 初始化前 postProcessBeforeInitialization()
. 构造之后 加了 @PostConstruct 的方法
. 所有属性赋值之后 afterPropertiesSet()
.初始化方法 配置文件中指定的 init-method 方法
.初始化后 postProcessAfterInitialization()
.销毁之前 加了 @PreDestroy 的方法
.销毁方法 配置文件中指定的 destroy-method 方法

Spring的Bean的生命周期方法执行顺序测试的更多相关文章

  1. Spring中Bean的生命周期方法

    Bean的生命周期方法 src\dayday\Car.java package dayday;import com.sun.org.apache.xpath.internal.SourceTree;i ...

  2. Spring(十二):IOC容器中Bean的生命周期方法

    IOC容器中Bean的生命周期方法 1)Spring IOC容器可以管理Bean的声明周期,Spring允许在Bean生命周期的特定点执行定制的任务. 2)Spring IOC容器对Bean的生命周期 ...

  3. 一次性讲清楚spring中bean的生命周期之一:getSingleton方法

    要想讲清楚spring中bean的生命周期,真的是不容易,以AnnotationConfigApplicationContext上下文为基础来讲解bean的生命周期,AnnotationConfigA ...

  4. JAVA面试题:Spring中bean的生命周期

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...

  5. Spring中Bean的生命周期及其扩展点

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6106456.html Spring中Bean的管理是其最基本的功能,根据下面的图来了解Spr ...

  6. 简:Spring中Bean的生命周期及代码示例

    (重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...

  7. 通过BeanPostProcessor理解Spring中Bean的生命周期

    通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...

  8. 使用外部属性文件配置Bean以及Bean的生命周期方法

    1.使用外部属性文件配置Bean 在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean ...

  9. 一分钟掌握Spring中bean的生命周期!

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean 的别名只能维持 ...

随机推荐

  1. mysql 数据库的时间与字符串转换

    .当前日期.时间 now() 获取 当前日期和时间 :: curdate() 当前日期, curtime() 当前时间 :: current_time() : //同curtime(),current ...

  2. 03 c++中this指针

    概念: 成员函数:在类中定义的函数.普通函数无法被继承,成员函数可以被继承.友元函数相当于普通函数. 友元函数不是类的组成,没有this指针,必须将成员函数操作符作为参数传递对象. 在c++中成员函数 ...

  3. 圆柱模板行业B2B站点打造MIP推送+熊掌号推送+历史普通推送插件

    最近因为做聚合页面http://zhimo.yuanzhumuban.cc/hotkey/list-951.html  内部站点关键词拥有5万的行业词库,所以这么多搜索词库,如何让百度第一时间抓取呢? ...

  4. HDFS中的数据块(Block)

    我们在分布式存储原理总结中了解了分布式存储的三大特点: 数据分块,分布式的存储在多台机器上 数据块冗余存储在多台机器以提高数据块的高可用性 遵从主/从(master/slave)结构的分布式存储集群 ...

  5. c#嵌套CMD窗口

    解决方法一: 自己放一个文本框,改成黑色,然后输入命令,执行时,你Process.Start cmd ,此时CMD窗口不显示,然后,将CMD的返回值,再取出来,设回文本框. 如何用这种方法实时获取cm ...

  6. mui 点击长按复制文本

    项目需要长按复制文本内容,由于也没仔细研究过 mui 所以就直接百度.看到了 花落乱了流年 这篇博客 我就把这个博客的代码融合到自己的项目里,实现了复制的需求 直接上代码 单独写到了一个 js 文件. ...

  7. CSP2019 爆炸记

    前言 第一次去参加\(csp\),被吊打,很慌. 之前\(NOIp\)普及组勉强一等,很慌. 考的也不是很好吧,很慌. 反正菜就对了. day -? 初赛,旁边坐着本校高三爷. 初赛比之前的模拟题简单 ...

  8. postgresql分布式集群之citus简介(转载)

    一.Citus是什么 citus是PG的一个sharding插件,可以把PG变成一个分布式数据库.目前在苏宁有大量的生产应用跑在citus+pg的环境中.大家可以看it大咖视频. citus是一款基于 ...

  9. PostgreSQL 查看表、索引等创建时间

    select s.oid,s.relname,t.stausename,t.stasubtype from pg_class s,pg_stat_last_operation t where s.re ...

  10. 2-STM32+W5500+GPRS物联网开发基础篇-基础篇学习的内容

    https://www.cnblogs.com/yangfengwu/p/10936553.html 这次的基础篇为公开篇,将公开所有基础篇的资料和源码 现在说一下基础篇准备公开的内容:(大部分哈,要 ...