当使用术语“生命周期”时,Spring的家伙指的是您的bean的构造和破坏,通常这与Spring Context的构造和破坏有关。 在某些情况下,Bean生命周期的管理不是一件容易的事,因为需要它执行自己的内部设置。 当您的bean必须与外部系统进行交互时,通常包括:加载文件,打开套接字或从数据库中读取一些数据,这通常是正确的。 它到底有什么关系,要解决这个问题,您所需要的只是让Spring在加载Spring Context并将其关闭时调用您的bean。

为此,Spring提供了三种在初始化和关闭期间调用代码的方式。 这些是:

  • 以编程方式,通常称为“接口回调”。
  • 以每个bean为基础进行声明,称为“方法回调”。
  • 通过对所有bean应用相同的默认方法回调进行声明。

接口回调是我之前所描述的。 但是,为了总结该技术并确保Spring在设置和删除Spring Context期间调用您的bean,您的bean必须实现特定的接口。 在初始化的情况下,它是InitializingBean ;在关闭的情况下,它是DisposableBean 。 如果您需要更多有关这些技术的知识,那么这里是有关InitializingBean的博客和有关DisposableBean 的博客 。

我实际上认为“方法回调”这个名称有些误导,因为它并未真正描述正在发生的事情。 使用方法回调时,您正在做的是将方法添加到bean中,然后在XML配置中引用该方法。 当Spring读取配置文件时,它会发现有一个类型为X的bean,其中有一个方法需要在启动时调用,而另一个方法则需要在关闭时调用。

现在我们需要一个方案,并且因为使用bean回调方法的原因之一是您可以初始化外部系统,所以我建议您正在为一家直销公司工作,并且已经获得编写其中一个烦人的应用程序的工作,该应用程序在半夜拨打随机数字并向接收方播放一条记录的消息,告诉接收方如何通过起诉某家公司来获得意外伤害赔偿(又名现金)他们从未有过。

这个想法是Dialer是一个外部系统,您必须为其编写控制器。 当控制器启动时,它必须连接至拨号器,而在其关闭时,请断开连接。

/*** Dial the number** @param phoneNumber*            the phone number as a string* @return true if the number is dialed successfully*/public boolean dial(String phoneNumber);/*** Play a message*/public void playMessge();/*** Hang up the line...*/public boolean hangUp();

DialerController由上面的接口定义,并且您可以期望它具有一些电话类型的方法,例如playMessage() dial(...)playMessage()hangUp() 。 接下来要做的是创建一个实现这些方法的bean,我将在下面完成。

@Component
public class DialerControllerImpl implements DialerController {private boolean connected;@Overridepublic boolean dial(String phoneNumber) {boolean retVal = false;if (isMiddleOfTheNight()) {testConnection();System.out.println("Dialing number: " + phoneNumber);retVal = true;}return retVal;}private boolean isMiddleOfTheNight() {return true;}@Overridepublic void playMessge() {testConnection();System.out.println("Hello, do not hang up you may be entitled to...");}@Overridepublic boolean hangUp() {testConnection();System.out.println("Hangup!");return true;}public void init() {connected = true;System.out.println("Connect to dialer");}public void destroy() {connected = false;System.out.println("Close connection to dialer");}private void testConnection() {if (connected == false) {throw new RuntimeException("Not connected to external system error");}}
}

playMessage() dial(...)playMessage()hangUp()方法没什么特别的; 他们检查Bean是否已连接到它正在对接的外部拨号程序,然后执行其工作。 此类的有趣之处在于init()destroy()方法,因为这是我们希望Spring在启动和关闭期间分别调用的方法。

为了确保Spring确实调用了我们的bean,我们需要在Spring配置XML中做些麻烦。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><bean id="dialerController" class="example_2_lifecycle_management.method_based.DialerControllerImpl" init-method="init" destroy-method="destroy" /></beans>

在此示例中,我使用了显式的bean配置(这意味着您可以忽略上面代码中的@Component属性,因为它目前尚未使用,但稍后需要使用),并且需要注意的是bean配置附加属性init-methoddestroy-method 。 这些用于定义Spring初始化和关闭时要调用的bean方法的名称。 在此示例中,它们对应于上面DialerControllerImpl类中的init()destroy()方法。

@Testpublic void testLifeCycle_using_per_bean_declaration() {ctx = new ClassPathXmlApplicationContext("dialer.xml");ctx.registerShutdownHook();instance = ctx.getBean(DialerControllerImpl.class);if (instance.dial("555-1234")) {instance.playMessge();instance.hangUp();}}

上面的代码演示了运行代码的简单单元测试(这不是真正的测试,因为它没有声明任何内容)。 这里要注意的要点是,在创建Spring Application Context之后,我添加了一个调用
registerShutdownHook() 。 这是因为您需要告诉JVM告诉Spring调用您的destroy()方法。 就像我在DisposableBean博客中所做的那样,您可以自己创建和处理shutdown钩子,有时这样做有很多好处,但在以后的日子里,还会有更多好处。

我现在听到的问题是“如果我使用自动装配会怎样?” 事实证明,Spring的Guys在Spring 3.1中添加了一种新的声明性方法回调技术,称为“默认方法回调”。 这里的一个大想法是,您在XML配置文件顶部的<beans/>元素中声明初始化和关闭方法的名称,如下所示:

<?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-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"default-init-method="init" default-destroy-method="destroy"><!-- Enable autowiring --><context:component-scan base-package="example_2_lifecycle_management.method_based" />
</beans>

选择bean生命周期技术时,请记住Spring专家建议您选择基于方法的回调而不是基于接口的回调。 原因是在选择接口回调路由时,您将bean绑定到了Spring。 这可能是(也可能不是)问题,而这实际上取决于您的应用程序的其余部分,因为使用其他许多Spring技术也会将您的应用程序绑定到Spring。

参考: Spring框架: Captain Debug博客博客中来自JCG合作伙伴 Roger Hughes的三种Spring Bean生命周期技术 。

翻译自: https://www.javacodegeeks.com/2013/02/spring-framework-three-spring-bean-lifecycle-techniques.html

Spring框架:三种Spring Bean生命周期技术相关推荐

  1. (转)Spring的三种实例化Bean的方式

    http://blog.csdn.net/yerenyuan_pku/article/details/52832793 Spring提供了三种实例化Bean的方式. 使用类构造器实例化. <be ...

  2. Spring IOC详解 以及 Bean生命周期详细过程 可以硬刚面试官的文章

    面试题 来自面试官发自灵魂深处的拷问:谈谈你对spring的理解: 一脸懵逼的求职者的内心活动:啥?  具体的问题是什么?现在的面试都不按套路出牌了吗?  抛出一个这么大的问题,你让我怎么回答? 一脸 ...

  3. Spring IOC 容器启动、Bean生命周期详解

    前言 在Spring IOC 和 AOP 概览中,简要介绍了IOC容器和AOP,没有深入IOC容器Bean的实例化,此文承接上文深入分析Bean的实例化过程.生命周期. Spring IOC的过程 S ...

  4. spring框架三种类型项目实现--基础maven类型、纯注解开发型、aop结合注解开发型

    spring框架实现 1.基础maven类型 1.开发准备--pom.xml添加spring依赖 2.创建properties文件 还是三层架构开发 3.domain层创建实体类javabean 4. ...

  5. Spring中三种配置Bean的方式

    1.使用xml配置文件 由Spring Framework本身决定,此处不详细说. 2.使用Java注解的配置 如果一个类使用了@Service,那么此类将自动注册成一个bean,不需要再在appli ...

  6. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)...

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  7. spring bean的init、destory的几种方法及生命周期

    个人总结spring-bean的声明周期维护有三种: 注解:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 xml中配置:xml中定义ini ...

  8. Spring Bean生命周期-obtainFreshBeanFactory(三)

    初始化ApplicationContext的时候,如果设置了自动刷新标志,会执行AbstractApplication的refresh方法,我们前篇文章提到了它的prepareRefresh方法,接下 ...

  9. Spring Bean 生命周期之“我从哪里来”?懂得这个很重要

    Spring bean 的生命周期很容易理解.实例化 bean 时,可能需要执行一些初始化以使其进入可用 (Ready for Use)状态.类似地,当不再需要 bean 并将其从容器中移除时,可能需 ...

最新文章

  1. 「AI大咖」ML宗师乔教主,全世界最有影响力的计算机科学家
  2. microscope image 3D reconstruction
  3. HDU 6833 A Very Easy Math Problem
  4. 如何判断自己是否到了该辞职的时候
  5. ubuntu查看python安装路径
  6. mysql 主键自增_还再使用数据库自增主键吗?
  7. 释放空间后将指针置空
  8. ekho--TTS语音引擎
  9. 图灵、冯诺依曼谁才配得上计算机之父?
  10. 【软件使用】Macbook M1 QuickTime录屏讲解(只录电脑或者同时录电脑和麦克风人声)
  11. Minesweeper 蓝桥杯 扫雷游戏(化繁为简)(摒弃多层循环)
  12. xamp安装及环境配置教程
  13. 【沉痛悼念】首届国医大师唐由之逝世 | 曾为毛主席治疗白内障
  14. linux panic 和 bug_on
  15. 软件测试之bug管理
  16. STM32学习笔记--DAC
  17. Java的String类中提到的代码点,代码单元到底是什么?
  18. 【List、Set、数据结构、Collections】
  19. 开源SCADA组态软件Qt,C#,和WEB大全
  20. 开发自己的操作系统(Hobby OS-deving)

热门文章

  1. (转)构建微服务:Spring boot 入门篇
  2. kafka命令行操作
  3. 如何基于tomcat构建web站点
  4. Docker-Desktop储存路径更改
  5. AQS的细节--自用,非正常教程
  6. oracle jdk_两个Oracle JDK的故事
  7. java 示例_功能Java示例 第2部分–讲故事
  8. java中精确地小数_在Java等于方法中进行精确比较
  9. Apache Kafka消费者再平衡
  10. 成为Java流大师–第6部分:使用流创建新的数据库应用程序