⭐️前面的话⭐️
本文已经收录到《Spring框架全家桶系列》专栏,本文将介绍Spring的生命周期的过程,以及基于xml配置文件的方式在程序中体现生命周期的过程。
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2023年4月19日🌴
✉️坚持和努力一定能换来诗与远方!
💭推荐书籍:📚《无》
💬参考在线编程网站:🌐牛客网🌐力扣🌐acwing
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
📌导航小助手📌
1.Bean的生命周期
Bean生命周期,顾名思义,它本质上就是生命周期的概念,就是描述某事物从诞生到消亡的过程,那Bean的生命周期指的就是Bean从诞生到消亡的过程,Bean的生命周期大致如下:
- 初始化Ioc容器。
- 创建对象,并分配内存。
- 执行构造方法。
- 执行属性注入,即执行
set
方法。 - 执行
bean
的初始化方法。 bean
对象已经实例化完成,可以使用bean
完成业务操作。- 任务执行完毕,
bean
对象进入销毁阶段,执行销毁前方法,并关闭容器。
总的来说,Bean
的生命周期分为三个阶段,1-5
属于实例化阶段,6
表示使用阶段,7
表示销毁阶段。
2.模拟Bean的生命周期
下面我们通过代码的方式来说明Bean的生命周期,项目的目录如下:
首先我们在LifeDao
除了写一个save
方法,再增加一个init
方法模拟初始化,destory
方法模拟销毁方法。
我们的验证程序如下:
我们将LifeDao注册到容器当中,xml配置如下:
我们直接这样写,肯定是不能够执行到init
和destory
方法的,我们需要进行配置,那不用说也知道,需要在xml中对lifeDao
进行配置,在bean
标签当中,init-method
属性可以指定初始化的方法是哪一个,destroy-method
属性可以指定销毁前执行的方法是哪一个,所以我们可以对这两个属性进行配置。
我们来看看运行结果:
我们发现init
方法执行了,但是destroy
方法并没有执行,这是因为我们的程序是在jvm虚拟机上执行的,当我们的验证代码执行完毕后,虚拟机也随之关闭了,并没有给destroy
方法执行的机会,下面我们来进行配置,让程序能够体现出destroy
方法的执行。
首先想到最暴力的方式,那就是在验证程序当中直接将容器销毁的过程运行一遍,容器销毁的过程中就会去执行对应容器中Bean对象的destroy
方法,那如何做呢?直接调用context
的close
方法即可,不过该方法在ApplicationContext
接口中是没有的,它是存在与ConfigurableApplicationContext
接口中,在后续的实现类中实现了close
方法。
所以我们需要通过使用ConfigurableApplicationContext
引用或者直接使用ClassPathXmlApplicationContext
引用来调用close
方法。
运行结果:
这是最直接最暴力的方法,处了这个方法,我们还可以利用注册钩子关闭容器的方式来实现,其实就是告诉jvm,在关闭jvm之前,先帮我把容器关掉,关好了再进行jvm虚拟机的销毁。
怎么注册钩子关闭容器呢?其实就是调用context
的registerShutdownHook
方法,这个方法同样在ApplicationContext
接口中是没有的,需要使用其实现类引用来进行调用。
运行结果:
既然close
方法和registerShutdownHook
方法都可以在jvm销毁前关闭容器,那这两者的区别是什么呢?
close
方法的含义是关闭当前的容器,也就是说,只要执行该方法,就会将容器关闭,并执行destory
方法,执行该方法后因为容器销毁了,那如果在业务执行完毕之前就销毁,那业务代码就无法取到容器中的对象,就会发生异常报错。registerShutdownHook
方法的含义是给jvm一个标记,告诉jvm在注销之前记得关闭容器,该方法在任何地方执行的效果都是一样的,只会在jvm注销前执行。
分析上面的实现过程,会发现添加初始化和销毁方法,即需要编码也需要配置,实现起来步骤比较多也比较乱。
最后还有一种方法,是通过实现接口的方式来说明Bean的生命周期过程,这样写的好处是不需要在xml文件当中设置init-method
方法和destroy-method
属性。
接下来在LifeServiceImpl完成这两个接口的使用:
修改LifekServiceImpl类,添加两个接口InitializingBean
, DisposableBean
并实现接口中的两个方法afterPropertiesSet
和destroy
。
afterPropertiesSet
方法表示在set
方法执行后执行,一般用来进行bean
的初始化操作,可见bean
的初始化在set
注入属性之后执行。
destroy
方法就是表示bean
对象的销毁过程了。
验证代码:
执行结果:
3.总结
(1)关于Spring中对bean生命周期控制提供了两种方式:
- 在配置文件中的bean标签中添加
init-method
和destroy-method
属性。 - 类实现
InitializingBean
与DisposableBean
接口。
(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:
- 初始化Ioc容器。
- 创建对象,并分配内存。
- 执行构造方法。
- 执行属性注入,即执行
set
方法。 - 执行
bean
的初始化方法。 bean
对象已经实例化完成,可以使用bean
完成业务操作。- 任务执行完毕,
bean
对象进入销毁阶段,执行销毁前方法,并关闭容器。
(3)关闭容器的两种方式:
ConfigurableApplicationContext
是ApplicationContext
的子接口,里面包含close()
方法和registerShutdownHook()
方法可以实现关闭容器。
两者的区别:
close
方法的含义是关闭当前的容器,也就是说,只要执行该方法,就会将容器关闭,并执行destory
方法,执行该方法后因为容器销毁了,那如果在业务执行完毕之前就销毁,那业务代码就无法取到容器中的对象,就会发生异常报错。registerShutdownHook
方法的含义是给jvm一个标记,告诉jvm在注销之前记得关闭容器,该方法在任何地方执行的效果都是一样的,只会在jvm注销前执行。