[Spring Framework]bean的生命周期以及控制

网友投稿 280 2022-09-16

[Spring Framework]bean的生命周期以及控制

文章目录

​​bean的生命周期控制(配置文件法)​​​​容器的关闭​​​​bean的生命周期控制(实现接口法)​​​​总结​​

bean的生命周期控制(配置文件法)

bean的生命周期就是bean对象从创建到销毁的整体过程。

我们在bean的生命周期中可以干一些事情(也就是对他的生命周期进行一些控制),例如创建之后(比如用来初始化需要用到资源),销毁之前(比如用来释放用到的资源)。

接下来我们进行尝试:

首先项目背景:

有一个实现了BookDao接口的是实现类BookDaoImpl:

public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); }}

我们把它放到IOC容器中:

接下来我们就以这个实现类BookDaoImpl为例子:

首先我们在实现类BookDaoImpl中编写两个方法,分别对应着初始化方法、销毁方法:

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..."); }}

注意这两个方法不能有返回值,不要有参数!

然后我们在Spring的配置文件中对他们进行配置,是他们真正的成为生命周期的控制方法:

用​​init-method​​来配置初始化方法用​​destroy-method​​来配置销毁方法

这样就完成了,接下来我们运行程序:

public class App3 { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); bookDao.save(); }}

结果为:

我们发现销毁方法并没有执行,这是为什么呢?

Spring的IOC容器是运行在JVM中,运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行,main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了,所以没有调用对应的destroy方法。

容器的关闭

如果我们想要销毁方法生效,那么我们就要在jvm关闭之前就把IOC容器进行关闭,而这里关闭IOC容器有两种方式:

close关闭容器注册钩子关闭容器

首先我们说说如何使用close关闭容器。要想使用close方法,那么得先有close方法:

close方法是从ConfigurableApplicationContext接口之后才开始有的,也就是说如果你写成如下是调用不了close方法的:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

如上是一个注意点,好在我们的代码是没有这种问题的:

然后调用close方法即可:

public class App3 { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); bookDao.save(); ctx.close(); }}

结果:

然后我们再注册钩子关闭容器,

在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器调用ctx的registerShutdownHook()方法

ctx.registerShutdownHook();

注意:registerShutdownHook在ApplicationContext中也没有

public class App3 { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); bookDao.save();// ctx.close(); ctx.registerShutdownHook(); }}

结果:

这两种关闭方法的区别在于:close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用关闭。

bean的生命周期控制(实现接口法)

分析上面的实现过程,会发现添加初始化和销毁方法,即需要编码也需要配置,实现起来步骤比较多也比较乱。

Spring提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置​​init-method​​​和​​destroy-method​​

我们接下来进行试验:

添加项目背景:

现在有一个实现了BookService接口的BookServiceImpl类,它依赖于BookDao:

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(); }}

我们以他为例子,首先实现两个接口​​InitializingBean​​​, ​​DisposableBean​​​并实现接口中的两个方法​​afterPropertiesSet​​​和​​destroy​​:

public class BookServiceImpl implements BookService, DisposableBean, InitializingBean { private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public void destroy() throws Exception { System.out.println("service destroy"); } public void afterPropertiesSet() throws Exception { System.out.println("service init"); } public void save() { System.out.println("book service save ..."); bookDao.save(); }}

在配置文件中,我们可以不使用那两个配置项:

执行结果:

还有一个注意点:

对于InitializingBean接口中的afterPropertiesSet方法,翻译过来为​​属性设置之后​​。对于BookServiceImpl来说,bookDao是它的一个属性。setBookDao方法是Spring的IOC容器为其注入属性的方法。setBookDao应该在afterPropertiesSet之前执行。推广一下初始化方法会在类中属性设置之后执行。

我们实验一下:

在setBookDao中添加一个打印语句:

public class BookServiceImpl implements BookService, DisposableBean, InitializingBean { private BookDao bookDao; public void setBookDao(BookDao bookDao) { System.out.println("set property...."); this.bookDao = bookDao; } public void destroy() throws Exception { System.out.println("service destroy"); } public void afterPropertiesSet() throws Exception { System.out.println("service init"); } public void save() { System.out.println("book service save ..."); bookDao.save(); }}

然后我们再执行,结果如下:

总结

(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()方法

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:[Spring Framework]核心概念(IOC/DI、IOC容器和Bean)、IOC初次使用
下一篇:Vue核心④(计算属性)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~