日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java钩子函数(hook)以spring源码为例

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java钩子函数(hook)以spring源码为例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、什么是鉤子函數

請問在Spring中,如果JVM異常終止,Spring是如何保證會釋放掉占用的資源,比如說數據庫連接等資源呢?鉤子函數非常簡單,簡單到只用摘抄一段Spring代碼即可。

二、問題

Spring 容器中 Bean 在什么時候執行銷毀方法?我們知道在Spring中定義銷毀方法有兩種方式實現DisposableBean 的 destroy 方法。 使用 @PreDestroy 注解修飾方法

@Component public class DataCollectBean implements DisposableBean {/*** 第一種方法實現 DisposableBean#destroy方法** @throws Exception 異常*/@Overridepublic void destroy() throws Exception {System.err.println("執行銷毀方法");}/*** 第二種方法使用PreDestroy注解聲明銷毀方法*/@PreDestroypublic void customerDestroy() {System.err.println("執行自定義銷毀方法");} }

三、那么在什么時候執行銷毀方法?

  • 主動執行銷毀bean
  • public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);DataCollectBean bean = run.getBean(DataCollectBean.class);//1. 主動銷毀beanrun.getBeanFactory().destroyBean(bean); }
  • JVM關閉時候自動執行銷毀方法。
    這里就要用到鉤子函數了, Spring 的鉤子函數在 AbstractApplicationContext#shutdownHook屬性,如果我們是SpringBoot項目我們看到在SpringApplication啟動時候會注冊一個鉤子函數
  • 四、如何定義鉤子函數?

    簡直太簡單了,沒有任何學習成本。一行代碼就能搞定。

    public class HooksTester {public static void main(String[] args) {//定義鉤子函數Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {@Overridepublic void run() {System.out.println("鉤子函數執行");}}));//當主動關閉應用while (true);} }

    五、觸發鉤子函數的場景

    只要不是機器斷電,強制kill -9 強制殺進程,都會觸發。

    六、鉤子函數能做什么?

    正如上圖所示優雅停機,在項目將要關閉時候,主動釋放程序占用的資源信息,釋放db連接池的連接等其他占用的資源信息。如果我們是 Spring 項目其實我們不用自己定義鉤子函數,我們只要使用Spring提供的銷毀方法即可。因為Spring定義的鉤子函數中會執行DisposableBean.destory() 和被 PreDestroy 修飾的方法。

    • 源碼
    protected void doClose() {// Check whether an actual close attempt is necessary...if (this.active.get() && this.closed.compareAndSet(false, true)) {if (logger.isDebugEnabled()) {logger.debug("Closing " + this);}LiveBeansView.unregisterApplicationContext(this);try {// Publish shutdown event.publishEvent(new ContextClosedEvent(this));}catch (Throwable ex) {logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);}// Stop all Lifecycle beans, to avoid delays during individual destruction.if (this.lifecycleProcessor != null) {try {this.lifecycleProcessor.onClose();}catch (Throwable ex) {logger.warn("Exception thrown from LifecycleProcessor on context close", ex);}}// Destroy all cached singletons in the context's BeanFactory.destroyBeans();// Close the state of this context itself.closeBeanFactory();// Let subclasses do some final clean-up if they wish...onClose();// Reset local application listeners to pre-refresh state.if (this.earlyApplicationListeners != null) {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Switch to inactive.this.active.set(false);}}

    可以看到:doClose()方法會執行bean的destroy(),也會執行SmartLifeCycle的stop()方法,我們就可以通過重寫這些方法來實現對象的關閉,生命周期的管理,實現平滑shutdown

    文章轉自

    總結

    以上是生活随笔為你收集整理的java钩子函数(hook)以spring源码为例的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。