成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring的Lifecycle和SmartLifecycle,可以沒用過,但不能不知道!

開發 架構
需要基于Spring容器的生命周期來處理一些邏輯時,通常可以實現SmartLifecycle接口來完成。像Spring Cloud,Spring Boot中都有大量的實踐案例。所以,無論實戰或閱讀源碼,不了解Lifecycle相關接口,都是一種損失。

[[401794]]

本文轉載自微信公眾號「程序新視界」,作者二師兄。轉載本文請聯系程序新視界公眾號。

前言

在使用Spring的過程中,我們通常會用@PostConstruct和@PreDestroy在Bean初始化或銷毀時執行一些操作,這些操作屬于Bean聲明周期級別的。

那么,就存在一些遺漏的場景,比如我們想在容器本身的生命周期(比如容器啟動、停止)的事件上做一些工作,很典型的就是Spring Boot中啟動內嵌的Web容器。該怎么辦?

這就需要用到Spring提供的另外一個接口Lifecycle。這篇文件就介紹一下Lifecycle接口,以及比它更聰明(Smart)的SmartLifecycle。

Lifecycle接口

Lifecycle是一個接口,它的作用是讓開發者可以在所有的bean都創建完成(getBean)之后執行自己的初始化工作,或者在退出時執行資源銷毀工作。

Lifecycle定義了三個方法,任何Bean實現了Lifecycle方法,當ApplicationContext收到start、stop和restart等信號時,就會調用對應的方法。因此可以通過實現Lifecycle接口獲得容器生命周期的回調,實現業務擴展。

LifeCycle定義如下:

  1. public interface Lifecycle { 
  2.  
  3.     void start(); 
  4.  
  5.     void stop(); 
  6.  
  7.     boolean isRunning(); 

自定義Lifecycle實現類

首先我們來自定義一個類,實現Lifecycle接口,來看看具體的實踐效果:

  1. @Component 
  2. public class MyLifeCycle implements Lifecycle { 
  3.  
  4.     /** 
  5.      * 運行狀態 
  6.      */ 
  7.     private volatile boolean running = false
  8.  
  9.     /** 
  10.      * 容器啟動后調用 
  11.      */ 
  12.     @Override 
  13.     public void start() { 
  14.         System.out.println("容器啟動后執行MyLifeCycle操作..."); 
  15.         running = true
  16.     } 
  17.  
  18.     /** 
  19.      * 容器停止時調用 
  20.      */ 
  21.     @Override 
  22.     public void stop() { 
  23.         System.out.println("收到關閉容器的信號MyLifeCycle操作..."); 
  24.         running = false
  25.     } 
  26.  
  27.     /** 
  28.      * 檢查此組件是否正在運行。 
  29.      * 1. 只有該方法返回false時,start方法才會被執行。 
  30.      * 2. 只有該方法返回true時,stop(Runnable callback)或stop()方法才會被執行。 
  31.      */ 
  32.     @Override 
  33.     public boolean isRunning() { 
  34.         System.out.println("檢查MyLifeCycle組件的運行狀態:" + running); 
  35.         return running; 
  36.     } 

單純的將上述代碼添加的Spring Boot項目當中,你會發現啟動時并沒有打印出任何相關的日志,只有在關閉應用時會打印出:

  1. 檢查MyLifeCycle組件的運行狀態:false 

這是因為,在SpringBoot或Spring應用中如果沒有調用AbstractApplicationContext#start方法,只是實現了Lifecycle接口,是不會執行Lifecycle接口中的啟動方法和isRunning方法的。但在應用退出時會執行Lifecycle#isRunning方法判斷該Lifecycle是否已經啟動,如果返回true則調用Lifecycle#stop()停止方法。

這個實例有一個很明顯的問題,那就是需要使用者顯式的調用容器的start()和stop()方法,Lifecycle的接口方法才會被執行。

而在一般的項目中,我們很少這樣顯式的去調用,所以就需要一個更“聰明”的類來處理,這就是SmartLifecycle。

SmartLifecycle

SmartLifecycle繼承自Lifecycle,提供了更豐富的功能:第一,start()方法無需容器顯式調用就可以被執行;第二,可以控制多SmartLifecycle實例的執行順序。

先來看一下SmartLifecycle接口的源碼:

  1. public interface SmartLifecycle extends Lifecycle, Phased { 
  2.     int DEFAULT_PHASE = 2147483647; 
  3.  
  4.     default boolean isAutoStartup() { 
  5.         return true
  6.     } 
  7.  
  8.     default void stop(Runnable callback) { 
  9.         this.stop(); 
  10.         callback.run(); 
  11.     } 
  12.  
  13.     default int getPhase() { 
  14.         return 2147483647; 
  15.     } 

可以看出該接口除了繼承Lifecycle接口外,還繼承了Phased。其中getPhase方法便是來自Phased。也正是基于Phased接口的這個方法來控制SmartLifecycle的執行順序的。

來看一下實例代碼:

  1. @Component 
  2. public class MySmartLifecycle implements SmartLifecycle { 
  3.  
  4.     private volatile boolean running = false
  5.  
  6.     /** 
  7.      * 如果該`Lifecycle`類所在的上下文在調用`refresh`時,希望能夠自己自動進行回調,則返回`true`, 
  8.      * false的值表明組件打算通過顯式的start()調用來啟動,類似于普通的Lifecycle實現。 
  9.      */ 
  10.     @Override 
  11.     public boolean isAutoStartup() { 
  12.         return true
  13.     } 
  14.  
  15.     /** 
  16.      * SmartLifecycle子類的才有的方法,當isRunning方法返回true時,該方法才會被調用。 
  17.      * 很多框架中的源碼中,都會把真正邏輯寫在stop()方法內。 
  18.      * 比如quartz和Redis的spring支持包。 
  19.      */ 
  20.     @Override 
  21.     public void stop(Runnable callback) { 
  22.         System.out.println("MySmartLifecycle容器停止,執行回調函數"); 
  23.         stop(); 
  24.         // 如果你讓isRunning返回true,需要執行stop這個方法,那么就不要忘記調用callback.run()。 
  25.         // 否則在程序退出時,Spring的DefaultLifecycleProcessor會認為這個MySmartLifecycle沒有stop完成,程序會一直卡著結束不了,等待一定時間(默認超時時間30秒)后才會自動結束。 
  26.         callback.run(); 
  27.     } 
  28.  
  29.     /** 
  30.      * 1. 主要在該方法中啟動任務或者其他異步服務,比如開啟MQ接收消息<br/> 
  31.      * 2. 當上下文被刷新(所有對象已被實例化和初始化之后)時,將調用該方法, 
  32.      * 默認生命周期處理器將檢查每個SmartLifecycle對象的isAutoStartup()方法返回的布爾值。 
  33.      * 如果為“true”,則該方法會被調用,而不是等待顯式調用自己的start()方法。 
  34.      */ 
  35.     @Override 
  36.     public void start() { 
  37.         System.out.println("MySmartLifecycle容器啟動完成 ..."); 
  38.         running = true
  39.     } 
  40.  
  41.     /** 
  42.      * 接口Lifecycle子類的方法,只有非SmartLifecycle的子類才會執行該方法。<br/> 
  43.      * 1. 該方法只對直接實現接口Lifecycle的類才起作用,對實現SmartLifecycle接口的類無效。<br/> 
  44.      * 2. 方法stop()和方法stop(Runnable callback)的區別只在于,后者是SmartLifecycle子類的專屬。 
  45.      */ 
  46.     @Override 
  47.     public void stop() { 
  48.         System.out.println("MySmartLifecycle容器停止 ..."); 
  49.         running = false
  50.     } 
  51.  
  52.     /** 
  53.      * 1. 只有該方法返回false時,start方法才會被執行。<br/> 
  54.      * 2. 只有該方法返回true時,stop(Runnable callback)或stop()方法才會被執行。 
  55.      */ 
  56.     @Override 
  57.     public boolean isRunning() { 
  58.         System.out.println("MySmartLifecycle檢查運行狀態 ..."); 
  59.         return running; 
  60.     } 
  61.  
  62.     /** 
  63.      * 如果有多個實現接口SmartLifecycle的類,則這些類的start的執行順序按getPhase方法返回值從小到大執行。<br/> 
  64.      * 例如:1比2先執行,-1比0先執行。stop方法的執行順序則相反,getPhase返回值較大類的stop方法先被調用,小的后被調用。 
  65.      * 
  66.      */ 
  67.     @Override 
  68.     public int getPhase() { 
  69.         return 0; 
  70.     } 

關于每個方法的功能,注釋部分已經明確說明了,下面啟動SpringBoot項目,打印日志如下:

  1. MySmartLifecycle檢查運行狀態 ... 
  2. MySmartLifecycle容器啟動完成 ... 

關閉SpringBoot項目,打印日志如下:

  1. MySmartLifecycle檢查運行狀態 ... 
  2. MySmartLifecycle容器停止,執行回調函數 
  3. MySmartLifecycle容器停止 ... 

通過上述實例可以看出:如果一個Bean實現了SmartLifecycle接口,則會執行啟動方法。SmartLifecycle#isRunning判斷是否已經執行,返回false表示還未執行,則調用SmartLifecycle#start()執行。

當關閉時,同樣先檢查運行狀態,如果正在運行,則執行關閉操作。關閉時,還可以處理對應的回調函數。

其中,Phased返回值越小,優先級越高。

小結

 

當需要基于Spring容器的生命周期來處理一些邏輯時,通常可以實現SmartLifecycle接口來完成。像Spring Cloud,Spring Boot中都有大量的實踐案例。所以,無論實戰或閱讀源碼,不了解Lifecycle相關接口,都是一種損失。本文的產生也是在遇到Spring Cloud集成Nacos的源碼中獲得的靈感。

 

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2017-12-25 13:26:36

CNN深度學習網絡

2020-08-18 10:51:18

AIoT數據泄露網絡攻擊

2019-07-08 10:40:03

線程池策略CPU

2024-06-03 00:00:05

2016-12-15 17:15:44

2017-01-16 15:01:27

中安威士

2017-01-19 14:44:14

2018-04-16 10:54:00

數據中心UPS電池

2009-08-03 09:29:26

2009-06-22 14:17:00

2022-01-05 08:01:48

前端技術編程

2012-09-17 09:59:46

創業創業教訓創業家

2019-11-13 08:37:34

數據庫筒倉基礎架構

2010-04-12 16:59:52

Oracle性能診斷

2017-05-04 11:05:43

互聯網

2010-06-01 09:48:43

云計算CIO整合

2009-12-21 15:43:07

2012-11-23 10:57:44

Shell

2022-02-28 09:44:39

JDKJavaSpring

2017-07-26 10:08:06

FABDesign SuppAndroid
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩一区二区三区视频在线观看 | 亚洲精品国产成人 | 亚洲色片网站 | 99精品视频网 | 2021狠狠干 | 巨大荫蒂视频欧美另类大 | 成人在线视频免费看 | av黄色国产 | 中文字幕福利视频 | 国产亚洲精品综合一区 | 国产视频91在线 | 精品久久久久久久久久久 | 一区二区三区四区av | 欧美日韩亚洲系列 | 亚洲精品视频免费观看 | 久久久久久久久久久一区二区 | 美女天天操 | 国产精品.xx视频.xxtv | 国产激情三区 | 亚洲免费在线观看 | 91久久精品国产91久久性色tv | 欧美一区二区在线播放 | 国产一区二区三区四区hd | 久久久精品一区二区三区四季av | 国产精品美女www爽爽爽视频 | 国产精品毛片一区二区三区 | av影片在线 | hsck成人网| 国产成人精品午夜视频免费 | 亚洲一区二区三区视频免费观看 | 91玖玖| 亚洲精品久久嫩草网站秘色 | 久久久久久免费毛片精品 | 三极网站 | 亚洲成年影院 | 国产成人综合亚洲欧美94在线 | 精品二区 | 亚洲国产欧美91 | 亚洲一区精品在线 | 国产精品国产精品国产专区不片 | 奇米影视首页 |