1.5 bean的生命周期
- bean的实例化已经说完了,我们最后再来讲讲
bean的生命周期
。
我们主要来围绕着
bean生命周期控制
来学习,那么什么是生命周期呢?其实就是一个东西从创建到消亡的完整过程,比如人从出生到死亡的整个过程,我们称这是完整的生命周期
,那bean的生命周期
是什么呢?bean是对象,也就是这个对象从创建到销毁的整个过程,那我们要想做它的控制
,其实就是在它创建以后到销毁之前做一些事情,接下来我们在程序中来说说怎么控制它的生命周期👇👇
在这有一点和前边不同,现在我们在这运行的是
dao
,也就是我在这配置的虽然有Service、Dao
,但是我运行的时候只是拿的dao
,也就是Service并未参与到我们的程序之中,那我们现在就来控制一下dao的生命周期
,在这里主要有两个阶段,第一个阶段是bean创建之后
,我们想控制它做一些事情,比如说你这个bean前边加载
的时候要做一些数据的准备
,那你就可以在这个阶段做,另外一个就是在bean消亡之前
,我们做一些事情,那看来这里边需要两个操作来代表
它的前和后
,我们来定义两个方法👇👇。
在这里我们写的简单一点,只是为了看它的
运行效果
,加上这两个方法以后,我们去运行我们的程序,会发现,这两个方法是绝对不会运行的 👇👇,这是为什么呢?在BookDaoImpl
里边随随便便写两个方法就能代表它的初始化和销毁操作了吗?,显然是不行的❗❗
那应该怎么办,我们需要去
applicationContext.xml
配置文件中去做一些配置
👇👇我们现在在控的是dao
层的bean
,那肯定是在它上边加配置,它的运行是非常简单的👇👇,运行完我们会发现:init
执行了,destory
为什么没有执行呢?
接下来我们就来说说为什么这个销毁操作没有执行,其实说到这里我们还是要说一个东西,我们现在运行的程序是在
Java虚拟机
中,我们可以这么想,虚拟机启动了,然后IOC容器
加载了配置也启动了,然后把bean
初始化了,然后我们从里边拿到bean了,然后执行完了,下一个动作是什么?程序执行完了,虚拟机退出了,也就是虚拟机在退出
的时候没有给你的bean销毁的这样一个机会,那怎么做才能做到这件事呢?其实方式有两种,在这里我们简单学习一下👇👇
第一种
就是在你的虚拟机
退出去之前
,我把我这个容器给关闭了,我们一打,发现没有这个方法👇👇,这是因为我们现在调的这个ctx
是ApplicationContext
这个接口,这个接口是不具有
这个方法的,如果我们需要在我们的程序中正常关闭我们的容器,我们需要用ClassPathXmlApplicationContext
这个类就可以关了👇👇。
现在
close
就能用了,我们再来运行一下👇👇,运行之后我们就能看到destory()方法
被执行了🎉🎉
我们第一种方式是比较
暴力
的方式关闭容器,也就是我直接关闭了,对于我们的容器来说,还提供有另外一种方式来关闭容器,叫做:设置关闭钩子
🎈🎈。
怎么理解呢,说简单一点就是我容器启动以后,我先在那加了一个标记
,什么意思呢,你虚拟机
退之前呢别忘了让我容器关完你再退,就是这么一回事,我们来看看关闭钩子怎么去写👇👇。
把上边这句话加上以后,也就意味着我们的容器在启动以后,
如果要关虚拟机之前,把它的容器先关掉
,那么这样也是可以的,我们再来运行一下👇👇。
如果我们把注册钩子那句代码换一下位置也是可以的,也就是这个
关闭钩子在任何时间都可以
。对于以上两种关闭容器的区别我们要说一下:close关闭
相对来说比较暴力一些,如果你要把这句代码挪到上边去,这个效果就完全不一样了,假如我们将它放到如下位置👇👇,结果会报错👇👇
我们来分析报错的
原因
,我们创建一个容器,并且初始化以后,直接关闭
容器,那容器都关了,后边的事还能做吗,肯定是不能了,这个错误的意思就是你的容器要么没初始化,要么已经关闭了,但是我们看上图可以发现☝️☝️,对于bean的生命周期管理的操作,是不是也都运行了,在这我们区分了一下两种关闭容器方式的不同🎉🎉。
那有人就问了,以后我们用哪一种呢,其实这两种在我们
实际开发
中都不用写,我们最终做的是web应用
,关闭容器这件事应该伴随着tomcat
一块玩的,我们会在web中
继续学习这些东西,到这里我们就学完了生命周期
的控制操作,这时候又有一个问题了,我们在配置的时候,随便写一个名字配给init-method、destory-method
属性,那么Spring容器就觉得有点乱,干脆按照它的要求
来写,我们就省了这两个属性配置了🎉🎉
按照它的要求,那就必须按照它的套路来写,怎么做的呢,我们在
service的实现类
上面按照Spring接口
的方式来把它的生命周期给做一遍,在这里要实现两个接口:InitializingBean(初始化bean)、DisposableBean
,这两个接口对应一个方法,我们把它加上并运行一下👇👇
注意
:我们虽然用的是dao运行,但是我们的service的bean也是被加载的,所以该运行的还是会运行的❗❗❗
我们可以看到,运行结果是正确的,在这里我们又学习了一种
控制生命周期
的方法:就是使用接口的方式也能控制
,在这我们来学习一个小细节,初始化
的方法叫做:afterPropertiesSet
,怎么解释呢,after:在什么之后,在什么之后呢?PropertiesSet
:在属性设置之后,啥意思,注意观察,我在setBookDao
方法里边打印一句话,我们来观察它的运行时间,我们只观察set....
的执行时间和service init
的执行时间的顺序👇👇。
我们运行完可以发现 set…的执行时间在service init的执行时间
之前
,,也就是说:当你的属性设置完以后,才去运行
afterPropertiesSet()这个操作,所以它才叫afterPropertiesSet:在属性设置之后
。到这我们就学习完了Spring使用接口来控制bean的生命周期
这种方式,使用这种方式我们就不需要在配置文件中
去配属性了🎈🎈。
对于我们生命周期的控制,有两种格式,一个是
配置
的方式,一个是使用接口
的方式,对于这种方式我们了解一下就可以了,除了这两种控制生命周期的方式以外,我们还要了解我们bean在初始化的过程中都经历了哪些阶段👇👇
首先第一个阶段是创建对象,分配内存
,我们可以理解为是new
在做的事情,然后执行构造方法
,构造方法执行完以后,整个对象就创建完了,接下来才是我们的set操作
,也就是执行属性注入
,刚才我们也看到了,set操作是优先于
我们bean的初始化的,然后set操作
完成以后,才是执行bean的初始化方法
,这是初始化容器
的阶段,接下来就是我们的bean的销毁操作:执行bean销毁方法
了,注意:这是在关闭销毁容器之前完成的,这是关闭/销毁容器
阶段,至于你执行你的业务bean的操作
,比如我们调save
方法,这和前面两个阶段是不挨着的,它只能算是使用bean的整个过程
。
总结
以上就是我们
bean的生命周期的全部内容
,我们需要知道的是容器关闭前才会触发bean的销毁
,最后,如果有什么错误的话,大家可以私信我📬📬,希望大家多多关注+点赞+收藏 ^_^🙏🙏,你们的鼓励是我不断前进的动力💪💪!!!
转载:https://blog.csdn.net/hihielite/article/details/128578047