搜尋
首頁Javajava教程springboot應用程式服務啟動事件的監聽怎麼實現

    一、簡介

    Spring Boot提供了兩個介面:CommandLineRunner、ApplicationRunner,用於啟動應用程式時做特殊處理,這些程式碼會在SpringApplication的run()方法運行完成之前被執行。相對於之前章節為大家介紹的Spring的ApplicationListener介面自訂監聽器、Servlet的ServletContextListener監聽器。 使用二者的好處在於,可以方便的使用應用啟動參數,根據參數不同做不同的初始化操作。

    二、常用場景介紹

    實作CommandLineRunner和ApplicationRunner介面。通常用於應用啟動前的特殊程式碼執行,例如:

    • 將系統常用的資料載入到記憶體

    • 應用程式上一次運行的垃圾資料清理

    • 系統啟動成功後的通知的發送等

    #我透過實作CommandLineRunner接口,在應用程式啟動時載入了系統內常用的配置數據,如下圖所示。從資料庫載入到內存,以後使用該資料的時候只需要呼叫getSysConfigList方法,不需要每次使用該資料都去資料庫載入。節省系統資源、縮減資料載入時間。

    springboot應用程式服務啟動事件的監聽怎麼實現

    二、程式碼小實驗透過@Component定義方式實作

    CommandLineRunner:參數是字串陣列

    @Slf4j
    @Component
    public class CommandLineStartupRunner implements CommandLineRunner {
        @Override
        public void run(String... args){
            log.info("CommandLineRunner传入参数:{}", Arrays.toString(args));
        }
    }

    ApplicationRunner:參數被放入ApplicationArguments,透過getOptionNames()、getOptionValues()、getSourceArgs()取得參數

    @Slf4j
    @Component
    public class AppStartupRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args)  {
            log.info("ApplicationRunner参数名称: {}", args.getOptionNames());
            log.info("ApplicationRunner参数值: {}", args.getOptionValues("age"));
            log.info("ApplicationRunner参数: {}", Arrays.toString(args.getSourceArgs()));
        }
    }

    透過@Bean定義方式實作

    這種方式可以指定執行順序,注意前兩個Bean是CommandLineRunner,最後一個Bean是ApplicationRunner 。

    @Configuration
    public class BeanRunner {
        @Bean
        @Order(1)
        public CommandLineRunner runner1(){
            return new CommandLineRunner() {
                @Override
                public void run(String... args){
                    System.out.println("BeanCommandLineRunner run1()" + Arrays.toString(args));
                }
            };
        }
    
        @Bean
        @Order(2)
        public CommandLineRunner runner2(){
            return new CommandLineRunner() {
                @Override
                public void run(String... args){
                    System.out.println("BeanCommandLineRunner run2()" + Arrays.toString(args));
                }
            };
        }
    
        @Bean
        @Order(3)
        public ApplicationRunner runner3(){
            return new ApplicationRunner() {
                @Override
                public void run(ApplicationArguments args){
                    System.out.println("BeanApplicationRunner run3()" + Arrays.toString(args.getSourceArgs()));
                }
            };
        }
    }

    可以透過@Order設定執行順序

    三、執行測試

    #在IDEA Springboot啟動設定中加入下列參數,儲存後啟動應用程式

    springboot應用程式服務啟動事件的監聽怎麼實現

    #測試輸出結果:

    c.z.boot.launch.config.AppStartupRunner  : ApplicationRunner參數名稱: [name, age]
    c.z.boot.launch.config. AppStartupRunner  : ApplicationRunner參數值: [18]
    c.z.boot.launch.config.AppStartupRunner  : ApplicationRunner參數: [--name=zimug, --age=18]

    #BeanApplicationRunner run3()[-- name=zimug, --age=18]

    c.z.b.l.config.CommandLineStartupRunner  : CommandLineRunner傳入參數:[--name=zimug, --age=18]
    BeanCommandLineRunner run1()[--name =zimug, --age=18]
    e=18]
    BeanCommandLineRunner run2()[--name=zimug, --age=18]

    #筆者經過多次測試發現,在測試結果中,這個優先順序一直如此,但目前無法確定這是否為常態

    • ApplicationRunner執行優先權高於CommandLineRunner

    • #以Bean的形式運行的Runner優先權要低於Component註解加上implements Runner介面的方式

    • Order註解只能保證同類的CommandLineRunner或ApplicationRunner的執行順序,不能跨類別保證順序

    四、總結

    CommandLineRunner、ApplicationRunner的核心用法是一致的,就是用來應用啟動前的特殊程式碼執行。 ApplicationRunner的執行順序先於CommandLineRunner;ApplicationRunner將參數封裝成了對象,提供了取得參數名稱、參數值等方法,操作上會方便一些。

    五、問題總結

    這是筆者在實務上真實遇到的問題,就是我定義了多個CommandLineRunner的實作。出現奇怪的問題是:當你定義多個CommandLineRunner的實作的時候,其中一個或幾個將不會執行。

    分析:下面的程式碼是SpringBootApplication啟動專案之後會執行的程式碼,大家看程式碼中透過一個遍歷來啟動CommandLineRunner或是ApplicationRunner。也就是說,只有上一個CommandLineRunner執行完成之後,才會執行下一個CommandLineRunner,是同步執行的。

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
    		List<Object> runners = new ArrayList<>();
    		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    		AnnotationAwareOrderComparator.sort(runners);
    		for (Object runner : new LinkedHashSet<>(runners)) {
    			if (runner instanceof ApplicationRunner) {
    				callRunner((ApplicationRunner) runner, args);
    			}
    			if (runner instanceof CommandLineRunner) {
    				callRunner((CommandLineRunner) runner, args);
    			}
    		}
    	}

    所以,如果在CommandLineRunner某個實作run 方法體中呼叫了同步阻塞的API或是一個 while(true) 循環,在遍歷中處於該CommandLineRunner之後的其他實作將不會被執行。

    以上是springboot應用程式服務啟動事件的監聽怎麼實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述
    本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
    Java平台獨立性:與不同的操作系統的兼容性Java平台獨立性:與不同的操作系統的兼容性May 13, 2025 am 12:11 AM

    JavaachievesPlatFormIndependencethroughTheJavavIrtualMachine(JVM),允許Codetorunondifferentoperatingsystemsswithoutmodification.thejvmcompilesjavacodeintoplatform-interploplatform-interpectentbybyteentbytybyteentbybytecode,whatittheninternterninterpretsandectectececutesoneonthepecificos,atrafficteyos,Afferctinginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginging

    什麼功能使Java仍然強大什麼功能使Java仍然強大May 13, 2025 am 12:05 AM

    JavaispoperfulduetoitsplatFormitiondence,對象與偏見,RichstandardLibrary,PerformanceCapabilities和StrongsecurityFeatures.1)Platform-dimplighandependectionceallowsenceallowsenceallowsenceallowsencationSapplicationStornanyDevicesupportingJava.2)

    頂級Java功能:開發人員的綜合指南頂級Java功能:開發人員的綜合指南May 13, 2025 am 12:04 AM

    Java的頂級功能包括:1)面向對象編程,支持多態性,提升代碼的靈活性和可維護性;2)異常處理機制,通過try-catch-finally塊提高代碼的魯棒性;3)垃圾回收,簡化內存管理;4)泛型,增強類型安全性;5)ambda表達式和函數式編程,使代碼更簡潔和表達性強;6)豐富的標準庫,提供優化過的數據結構和算法。

    Java真的平台獨立嗎? '寫一次,在任何地方運行”如何起作用Java真的平台獨立嗎? '寫一次,在任何地方運行”如何起作用May 13, 2025 am 12:03 AM

    javaisnotirelyplatemententedduetojvmvariationsandnativecodinteinteration,butitlargelyupholdsitsitsworapromise.1)javacompilestobytecoderunbythejvm

    揭示JVM:您了解Java執行的關鍵揭示JVM:您了解Java執行的關鍵May 13, 2025 am 12:02 AM

    thejavavirtualmachine(JVM)IsanabtractComputingmachinecrucialforjavaexecutionasitrunsjavabytecode,使“ writeononce,runanywhere”能力

    Java仍然是基於新功能的好語言嗎?Java仍然是基於新功能的好語言嗎?May 12, 2025 am 12:12 AM

    Javaremainsagoodlanguageduetoitscontinuousevolutionandrobustecosystem.1)Lambdaexpressionsenhancecodereadabilityandenablefunctionalprogramming.2)Streamsallowforefficientdataprocessing,particularlywithlargedatasets.3)ThemodularsystemintroducedinJava9im

    是什麼使Java很棒?關鍵特徵和好處是什麼使Java很棒?關鍵特徵和好處May 12, 2025 am 12:11 AM

    Javaisgreatduetoitsplatformindependence,robustOOPsupport,extensivelibraries,andstrongcommunity.1)PlatformindependenceviaJVMallowscodetorunonvariousplatforms.2)OOPfeatureslikeencapsulation,inheritance,andpolymorphismenablemodularandscalablecode.3)Rich

    前5個Java功能:示例和解釋前5個Java功能:示例和解釋May 12, 2025 am 12:09 AM

    Java的五大特色是多態性、Lambda表達式、StreamsAPI、泛型和異常處理。 1.多態性讓不同類的對象可以作為共同基類的對象使用。 2.Lambda表達式使代碼更簡潔,特別適合處理集合和流。 3.StreamsAPI高效處理大數據集,支持聲明式操作。 4.泛型提供類型安全和重用性,編譯時捕獲類型錯誤。 5.異常處理幫助優雅處理錯誤,編寫可靠軟件。

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱門文章

    熱工具

    VSCode Windows 64位元 下載

    VSCode Windows 64位元 下載

    微軟推出的免費、功能強大的一款IDE編輯器

    WebStorm Mac版

    WebStorm Mac版

    好用的JavaScript開發工具

    mPDF

    mPDF

    mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器