c语言sscanf函数的用法是什么
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~