Java开发学习(五)----bean的生命周期
一、什么是生命周期
首先理解下什么是生命周期?
从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。
bean生命周期是什么?
bean对象从创建到销毁的整体过程。
bean生命周期控制是什么?
在bean创建后到销毁前做一些事情。
二、环境准备
环境搭建:
创建一个Maven项目
pom.xml添加依赖
resources下添加spring的配置文件applicationContext.xml
最终项目的结构如下:
(1)项目中添加BookDao、BookDaoImpl、BookService和BookServiceImpl类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
(2)resources下提供spring的配置文件
<?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.xsd">
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
(3)编写AppForLifeCycle运行类,加载Spring的IOC容器,并从中获取对应的bean对象
public class AppForLifeCycle {
public static void main( String[] args ) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
三、生命周期设置
接下来,在上面这个环境中来为BookDao添加生命周期的控制方法,具体的控制有两个阶段:
bean创建之后,想要添加内容,比如用来初始化需要用到资源
bean销毁之前,想要添加内容,比如用来释放用到的资源
步骤1:添加初始化和销毁方法
针对这两个阶段,我们在BooDaoImpl类中分别添加两个方法,方法名任意
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
//表示bean初始化对应的操作
public void init(){
System.out.println("init...");
}
//表示bean销毁前对应的操作
public void destory(){
System.out.println("destory...");
}
}
步骤2:配置生命周期
在配置文件添加配置,如下:
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
步骤3:运行程序
运行AppForLifeCycle打印结果为:
从结果中可以看出,init方法执行了,但是destroy方法却未执行,这是为什么呢?
Spring的IOC容器是运行在JVM中
运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行
main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了
所以没有调用对应的destroy方法
知道了出现问题的原因,具体该如何解决呢?
四、close关闭容器
ApplicationContext中没有close方法
需要将ApplicationContext更换成ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");调用ctx的close()方法
ctx.close();
运行程序,就能执行destroy方法的内容
这种方式比较暴力,直接就关闭掉容器了,接下来介绍另一种方式,
五、注册钩子关闭容器
在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器
调用ctx的registerShutdownHook()方法
是全局变量,方法放置位置无所谓
ctx.registerShutdownHook();
注意:registerShutdownHook在ApplicationContext中也没有
运行后,查询打印结果
两种方式介绍完后,close和registerShutdownHook选哪个?
相同点:这两种都能用来关闭容器
不同点:close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用关闭。
分析上面的实现过程,会发现添加初始化和销毁方法,即需要编码也需要配置,实现起来步骤比较多也比较乱。
Spring提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置init-method
和destroy-method
接下来在BookServiceImpl完成这两个接口的使用:
修改BookServiceImpl类,添加两个接口InitializingBean
, DisposableBean
并实现接口中的两个方法afterPropertiesSet
和destroy
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
public void destroy() throws Exception {
System.out.println("service destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("service init");
}
}
重新运行AppForLifeCycle类
那第二种方式的实现,我们也介绍完了。
小细节
对于InitializingBean接口中的afterPropertiesSet方法,翻译过来为
属性设置之后
。对于BookServiceImpl来说,bookDao是它的一个属性
setBookDao方法是Spring的IOC容器为其注入属性的方法
思考:afterPropertiesSet和setBookDao谁先执行?
从方法名分析,猜想应该是setBookDao方法先执行
验证思路,在setBookDao方法中添加一句话
public void setBookDao(BookDao bookDao) {
System.out.println("set .....");
this.bookDao = bookDao;
}
重新运行AppForLifeCycle,打印结果如下:
验证的结果和我们猜想的结果是一致的,所以初始化方法会在类中属性设置之后执行。
六、bean生命周期总结
(1)关于Spring中对bean生命周期控制提供了两种方式:
在配置文件中的bean标签中添加
init-method
和destroy-method
属性类实现
InitializingBean
与DisposableBean
接口。
(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:
初始化容器
1.创建对象(内存分配)
2.执行构造方法
3.执行属性注入(set操作)
4.执行bean初始化方法
使用bean
1.执行业务操作
关闭/销毁容器
1.执行bean销毁方法
(3)关闭容器的两种方式:
ConfigurableApplicationContext是ApplicationContext的子类
close()方法
registerShutdownHook()方法
Java开发学习(五)----bean的生命周期的更多相关文章
- Spring 学习笔记---Bean的生命周期
生命周期图解 由于Bean的生命周期经历的阶段比较多,我们将通过一个图形化的方式进行描述.下图描述了BeanFactory中Bean生命周期的完整过程: Bean 的生命周期从Spring容器着手实例 ...
- spring深入学习(二)-----bean的生命周期、IOC容器bean装配
bean的生命周期 1.实例化Bean对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBea ...
- Spring4学习笔记 - Bean的生命周期
1 Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1)通过构造器或工厂方法创建 Bean 实例 2)为 Bean 的属性设置值和对其他 Bean 的引用 3)调用 Bean 的初 ...
- Java多线程学习(三)---线程的生命周期
线程生命周期 摘要: 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态.在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(Running).阻塞 ...
- Java开发学习(三)----Bean基础配置及其作用范围
一.bean基础配置 对于bean的基础配置如下 <bean id="" class=""/> 其中,bean标签的功能.使用方式以及id和clas ...
- Java开发学习(四)----bean的三种实例化方式
一.环境准备 准备开发环境 创建一个Maven项目 pom.xml添加依赖 resources下添加spring的配置文件applicationContext.xml 最终项目的结构如下: 二. ...
- Spring Bean的生命周期,《Spring 实战》书中的官方说法
连着两天的面试 ,都问到了 Spring 的Bean的生命周期,其中还包括 昨晚一波阿里的电话面试.这里找到了Spring 实战中的官方说法.希望各位要面试的小伙伴记住,以后有可能,或者是有时间 去看 ...
- 深究Spring中Bean的生命周期
前言 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到也是一头雾水,直到看到了<Spring in action>这本书,书上 ...
- Spring02——Spring 中 Bean 的生命周期及其作用域
在前一篇文章中,我们已经介绍了 Spring IOC 的相关知识,今天将为个位介绍 Spring 中 Bean 的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java ...
随机推荐
- Python入门-程序测试
1.功能测试 常规测试 #常规测试代码,一个模块写功能,一个模块调用功能 #=============模块1:gongneng_ceshi def func(v1, v2): return v1* v ...
- 【面试普通人VS高手系列】Fail-safe机制与Fail-fast机制分别有什么作用
前段时间一个小伙伴去面试,遇到这样一个问题. "Fail-safe机制与Fail-fast机制分别有什么作用" 他说他听到这个问题的时候,脑子里满脸问号.那么今天我们来看一下,关于 ...
- 自家APP打开微信小程序,可行吗?
小程序的通用解决方案,今天为大家介绍一下FinClip.它的最大特点,就是能够让任何 App 运行小程序. 只需要在你的 App 里面,引入它的 SDK,就能加载运行外部小程序了.除了 SDK,它还提 ...
- c++中的类和对象_概念
类:事物所具有的共性(行为.属性)抽象出来封装在一起 对象:由类型实例化出对象 c++与c struct的区别:c中不能存放函数,只能存放属性,方法和属性分离,c++中则可存放函数. c中表示事物的方 ...
- Lumia1520 手机刷 Windows10 arm双系统
注意问题 升级到Windows 10 Mobile 的需重新刷回WP8.1,否则解锁会失败 部分手机刷机win10arm后出现屏幕卡死现象,目前除了换屏或重新焊接暂无其他解决方案,请谨慎刷机(当然如果 ...
- Java语言学习day26--7月01日
###14内部类 * A: 内部类的概述 将类写在其他类的内部,可以写在其他类的成员位置和局部位置,这时写在其他类内部的类就称为内部类. 其他类也称为外部类. * B: 什么时候使用内部类 在描述事物 ...
- Java枚举类与常用方法
小简博客 - 小简的技术栈,专注Java及其他计算机技术.互联网技术教程 (ideaopen.cn) 枚举类 如何创建 首先,从名字就可以看出,枚举是一个类,那么我们就可以直接在创建时选择枚举就可以. ...
- 论文解读(MERIT)《Multi-Scale Contrastive Siamese Networks for Self-Supervised Graph Representation Learning》
论文信息 论文标题:Multi-Scale Contrastive Siamese Networks for Self-Supervised Graph Representation Learning ...
- Oracle 数据库表删除重复数据
删除重复数据并保留一条 方法一 1.建立临时表,记录重复的数据 create table 临时表 as select a.字段1,a.字段2,max(a.rowid) as dataid from 原 ...
- Ubuntu 系统安装,VMware
系统版本 ubuntu-18.04.5-server-amd64.iso 1.自定义安装 2.默认下一步 3. 稍后安装操作系统 4.选择ubuntu 64位 5.选额安装的目录 6.设置虚拟机c ...