Spring Bean 的生命周期回调

Spring中的Bean是随着Spring容器产生的,当Spring容器关闭的时候,相应的Bean也会消失。当然这个和Bean自身的作用域范围也有关系,但是通常都逃不过 初始化,运行,关闭这三个状态。

在Spring中,我们通常需要在Bean刚刚初始化的时候,或者Bean被销毁的时候做一些额外的资源处理的事情。Spring提供了InitializingBean和DisposableBean接口,前者调用afterPropertiesSet(),为后者调用destroy(),以便bean在初始化和销毁bean时执行某些操作。

如下所示:

  1. public class SampleInitializingBean implements InitializingBean {
  2. @Override
  3. public void afterPropertiesSet() throws Exception {
  4. log.info("inside afterPropertiesSet");
  5. }
  6. }
  1. public class SampleDisposableBean implements DisposableBean {
  2. @Override
  3. public void destroy() throws Exception {
  4. log.info("destroy");
  5. }
  6. }

当然这样做就和Spring的代码耦合了。我们可以使用JSR-250 的@PostConstruct和@PreDestroy注解,这样就和Spring框架解耦了。

第三种方法就是使用配置的init-method和destroy-method,或者使用@Bean的initMethod属性和@Bean的destroyMethod属性。

如下所示:

  1. <bean id="exampleInitBean" class="com.flydean.beans.ExampleBean"
  2. init-method="init" destroy-method="destroy"/>

下面是@Bean注解的例子:

  1. @Bean(initMethod = "init",destroyMethod = "destroy")
  2. public ExampleBean getExampleBean(){
  3. return new ExampleBean();
  4. }

也可以为所有的bean都添加一个默认的初始化方法,和销毁方法:

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
  4. default-init-method="init" default-destroy-method="destroy">

总结生命周期机制

从Spring2.5之后,你有3种方式来控制bean的生命周期:

  • InitializingBean和DisposableBean回调接口
  • 自定义init() 和destroy() 方法。
  • @PostConstruct 和 @PreDestroy注解.

如果为initialization配置了多种生命周期的多个名字,那么执行顺序如下:

  • @PostConstruct 的方法注解
  • InitializingBean接口里面的afterPropertiesSet() 方法
  • 自定义的init() 方法

同样的Destroy也是一样的顺序:

  • @PreDestroy 的方法注解
  • DisposableBean接口里面的destroy() 方法
  • 自定义的destroy() 方法

startup和Shutdown回调

上面我们讲了在bean初始化和销毁的时候的回调。一般来说就已经够用了。如果需要自己管理生命周期对象,比如启动和停止一些后台进程的时候,Spring提供了Lifecycle接口。

  1. public interface Lifecycle {
  2. void start();
  3. void stop();
  4. boolean isRunning();
  5. }

任何Spring管理的对象都可以实现Lifecycle接口。当ApplicationContext收到一个start或者stop信号时,他会将该信号传递给所有的Lifecycle接口的实现。

Spring提供了LifecycleProcessor接口,该接口的默认实现是DefaultLifecycleProcessor :

  1. public interface LifecycleProcessor extends Lifecycle {
  2. /**
  3. * Notification of context refresh, e.g. for auto-starting components.
  4. */
  5. void onRefresh();
  6. /**
  7. * Notification of context close phase, e.g. for auto-stopping components.
  8. */
  9. void onClose();
  10. }

onRefresh()和onClose()会去调用实现了Lifecycle接口的start()和close()方法。

如果需要实现启动和关闭回调的顺序,则可以实现SmartLifecycle接口,该接口提供了getPhase()方法:

  1. public interface SmartLifecycle extends Lifecycle, Phased {
  2. boolean isAutoStartup();
  3. void stop(Runnable callback);
  4. }

启动时,具有最低phase的对象首先启动。停止时,按相反顺序执行。

优雅的关闭Spring IoC容器

如果是Spring WEB应用程序,Spring的web基础的ApplicationContext实现,已经有代码优雅的关闭 Spring IoC 容器。

这里我们考虑非web情况,我们需要注册一个shutdown hook到JVM中。这样将保证优雅的关闭,并且在单例bean中调用相关的销毁方法,让所有的资源得到释放。

调用ConfigurableApplicationContext接口中的registerShutdownHook()来注册一个shutdown hook, 如下所示:

  1. public static void main(final String[] args) throws Exception {
  2. ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("bean-lifecycle.xml");
  3. // add a shutdown hook for the above context...
  4. ctx.registerShutdownHook();
  5. // app runs here...
  6. // main method exits, hook is called prior to the app shutting down...
  7. }

本节的代码可以参考bean-lifecycle

更多教程请参考flydean的博客

Spring5参考指南:Bean的生命周期管理的更多相关文章

  1. Spring5参考指南:Bean作用域

    文章目录 Bean作用域简介 Singleton作用域 Prototype作用域 Singleton Beans 中依赖 Prototype-bean web 作用域 Request scope Se ...

  2. Spring5参考指南:Bean的创建

    文章目录 Spring容器中的Bean Bean的命名 Bean的实例化 Spring容器中的Bean Bean在Spring中就是一个业务组件,我们通过创建各种Bean来完成最终的业务逻辑功能. 在 ...

  3. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  4. IOC容器中bean的生命周期

    一.Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进行管理的过程如下: (1).通 ...

  5. Bean的生命周期

    Bean的生命周期 原文:http://997004049-qq-com.iteye.com/blog/1729793 任何一个事物都有自己的生命周期,生命的开始.生命中.生命结束.大家最熟悉的应该是 ...

  6. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring Bean的生命周期

    Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁. 而对于 protot ...

  7. 【Spring】Spring中的Bean - 4、Bean的生命周期

    Bean的生命周期 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean 了解Spring中Bean的生命周期有何意义? 了解Sp ...

  8. Spring4.0学习笔记(5) —— 管理bean的生命周期

    Spring IOC 容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务 Spring IOC 容器对Bean的生命周期进行管理的过程: 1.通过构造器或工厂方法 ...

  9. Spring Bean 的生命周期,如何被管理的?

    定义 Bean是一个被实例化,组装,并通过Spring IOC容器(BeanFactory和ApplicationContext容器)所管理的对象. 作用域 Spring支持五个作用域,分别是sing ...

随机推荐

  1. CAS / ABA

    CAS / ABA 标签(空格分隔): 操作系统 1. CAS 解决 Volatile 不保证原子性的问题 /** * Atomically increments by one the current ...

  2. vue中使用阿里图标库iconfont和在旧有的iconfont中添加新的图标

    第一步 下载样式http://www.iconfont.cn/选择图表,点击加入购物车 第二步 解压下载文件 第三步 修改文件名称 与 iconfont.css 名路径 第四步 将@font-face ...

  3. 【WPF学习】第六十六章 支持可视化状态

    上一章介绍的ColorPicker控件,是控件设计的最好示例.因为其行为和可视化外观是精心分离的,所以其他设计人员可开发动态改变其外观的新模板. ColorPicker控件如此简单的一个原因是不涉及状 ...

  4. GhostNet: 使用简单的线性变换生成特征图,超越MobileNetV3的轻量级网络 | CVPR 2020

    为了减少神经网络的计算消耗,论文提出Ghost模块来构建高效的网络结果.该模块将原始的卷积层分成两部分,先使用更少的卷积核来生成少量内在特征图,然后通过简单的线性变化操作来进一步高效地生成ghost特 ...

  5. Python库-Pandas

    Pandas是基于NumPy的一种数据分析工具,提供了大量使我们快速便捷处理数据的函数和方法. 中文官网地址:https://www.pypandas.cn Pandas基于两种数据类型:Series ...

  6. BMI的Python实现

    str1 = float(input('请输入您的身高(单位:米):')) # input默认转化为字符串型 用float转化为浮点型 str2 = float(input('请输入您的体重(单位:千 ...

  7. break与continue用法注意事项

    break 中断循环执行,跳出循环 注意,break只能中断自己所在的循环,一般用在内层循环,但是不能中断外层循环中的代码. continue 跳到循环的下一轮继续执行,结束自己所在循环体代码,继续自 ...

  8. shell命令(一)

    什么是shell? Shell是一个应用程序,它连接了用户和Linux内核,让用户能够更加高效.安全.低成本地使用Linux内核,这就是Shell的本质. shell与Linux系统关系图 shell ...

  9. AJ学IOS(54)多线程网络之NSOperation重要知识

    AJ分享,必须精品 一:队列的类型与队列添加任务 1: 主队列 [NSOperationQueue mainQueue] 添加到”主队列”中的操作,都会放到主线程中执行. 2:非主队列 [[NSOpe ...

  10. AJ学IOS(17)UI之纯代码自定义Cell实现新浪微博UI

    AJ分享,必须精品 先看效果图 编程思路 代码创建Cell的步骤 1> 创建自定义Cell,继承自UITableViewCell 2> 根据需求,确定控件,并定义属性 3> 用get ...