原创

spring回顾-生命周期方法

温馨提示:
本文最后更新于 2022年06月20日,已超过 7 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

在前面的学习中我们知道生命周期分为init和destory两种方法,使用这两种方法的时候需要在bean的实例对象中生命这两个方法,并且需要在application中创建对应的配置,让程序能够知道我们将哪两个方法作为生命周期方法

image-20220620090801934

执行结果

image-20220620090848152

发现销毁方法并不能被正常执行,原因是javajvm的销毁在容器的销毁之前,容器无法判断jvm什么时候被销毁,就不能正常执行销毁方法,正确的做法是手动销毁容器

close关闭容器

ClassPathXmlApplicationContext对象中存在一个close方法,专门用来关闭容器的,我们可以手动的在方法的末尾加上该方法,关闭容器

当然这是一种很暴力的方式,我们可以使用另外一种方式来关闭容器

注册钩子关闭容器

  • 在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器

  • 调用ctx的registerShutdownHook()方法

    ctx.registerShutdownHook();
    

    注意:registerShutdownHook在ApplicationContext中也没有

  • 运行后,查询打印结果

    image-20220620091541910

两种方式介绍完后,close和registerShutdownHook选哪个?

相同点:这两种都能用来关闭容器

不同点:close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用关闭。

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

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

接下来在BookServiceImpl完成这两个接口的使用:

修改BookServiceImpl类,添加两个接口InitializingBeanDisposableBean并实现接口中的两个方法afterPropertiesSetdestroy

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类,

image-20220620091625358

小细节

  • 对于InitializingBean接口中的afterPropertiesSet方法,翻译过来为属性设置之后

  • 对于BookServiceImpl来说,bookDao是它的一个属性

  • setBookDao方法是Spring的IOC容器为其注入属性的方法

  • 思考:afterPropertiesSet和setBookDao谁先执行?

    • 从方法名分析,猜想应该是setBookDao方法先执行

    • 验证思路,在setBookDao方法中添加一句话

      public void setBookDao(BookDao bookDao) {
              System.out.println("set .....");
              this.bookDao = bookDao;
          }
      
    • 重新运行AppForLifeCycle,打印结果如下:

      image-20220620091736654

总结

(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:

  • 初始化容器
    • 1.创建对象(内存分配)
    • 2.执行构造方法
    • 3.执行属性注入(set操作)
    • ==4.执行bean初始化方法==
  • 使用bean
    • 1.执行业务操作
  • 关闭/销毁容器
    • ==1.执行bean销毁方法==

(3)关闭容器的两种方式:

  • ConfigurableApplicationContext是ApplicationContext的子类
    • close()方法
    • registerShutdownHook()方法
正文到此结束