亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot啟動時執(zhí)行初始化操作的幾種方式

 更新時間:2024年05月01日 08:41:30   作者:strggle_bin  
項目中,經(jīng)常需要在啟動過程中初始化一些數(shù)據(jù),如從數(shù)據(jù)庫讀取一些配置初始化,或從數(shù)據(jù)庫讀取一些熱點數(shù)據(jù)到redis進行初始化緩存,本文給大家介紹了SpringBoot啟動時執(zhí)行初始化操作的幾種方式的相關(guān)資料,需要的朋友可以參考下

場景

項目中,經(jīng)常需要在啟動過程中初始化一些數(shù)據(jù),如從數(shù)據(jù)庫讀取一些配置初始化,或從數(shù)據(jù)庫讀取一些熱點數(shù)據(jù)到redis進行初始化緩存。

方式一:實現(xiàn)CommandLineRunner 接口重寫run方法邏輯

CommandLineRunner是Spring提供的接口,定義了一個run()方法,用于執(zhí)行初始化操作。

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class InitConfigCommand implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner:"+"{}"+"接口實現(xiàn)方式重寫");
    }
}

CommandLineRunner的執(zhí)行時機為Spring beans初始化之后,因此CommandLineRunner的執(zhí)行一定是晚于@PostConstruct的。

若有多組初始化操作,則每一組操作都要定義一個CommandLineRunner派生類并實現(xiàn)run()方法。這些操作的執(zhí)行順序使用@Order(n)來設(shè)置,n為int型數(shù)據(jù)。

@Component
@Order(99)
public class CommandLineRunnerA implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("初始化:CommandLineRunnerA");
    }
}

@Component
@Order(1)
public class CommandLineRunnerB implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("初始化:CommandLineRunnerB");
    }
}

如上,會先執(zhí)行CommandLineRunnerB的run(),再執(zhí)行CommandLineRunnerA的run()。

@Order(n)中的n較小的會先執(zhí)行,較大的后執(zhí)行。n只要是int值即可,無需順序遞增。

方式二:實現(xiàn)ApplicationRunner接口重寫run方法邏輯

ApplicationRunner接口與CommandLineRunner接口類似,都需要實現(xiàn)run()方法。二者的區(qū)別在于run()方法的參數(shù)不同:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class InitConfig implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("項目啟動初始化");
    }
}

ApplicationRunner接口的run()參數(shù)為ApplicationArguments對象,因此可以獲取更多項目相關(guān)的內(nèi)容。

ApplicationRunner接口與CommandLineRunner接口的調(diào)用時機也是相同的,都是Spring beans初始化之后。因此ApplicationRunner接口也使用@Order(n)來設(shè)置執(zhí)行順序。

方式三:使用@PostConstruct注解的方式

對于注入到Spring容器中的類,在其成員函數(shù)前添加@PostConstruct注解,則在執(zhí)行Spring beans初始化時,就會執(zhí)行該函數(shù)。

但由于該函數(shù)執(zhí)行時,其他Spring beans可能并未初始化完成,因此在該函數(shù)中執(zhí)行的初始化操作應(yīng)當不依賴于其他Spring beans。

@Component
public class Construct {
    @PostConstruct
    public void doConstruct() throws Exception {
        System.out.println("初始化:PostConstruct");
    }
}

初始化順序

  • @PostConstruct 注解方法
  • CommandLineRunner接口實現(xiàn)
  • ApplicationRunner接口實現(xiàn)

擴展

@PostConstruct注解使用在方法上,它可以被用來標注一個非靜態(tài)的 void 方法,這個方法會在該類被 Spring 容器初始化后立即執(zhí)行。因為它的執(zhí)行時機是在依賴注入之后,對象構(gòu)造完成之后,也就是說是在@Autowired注入之后執(zhí)行。所以這里可以進行一些初始化操作,如某些需要在對象創(chuàng)建后才能進行的數(shù)據(jù)初始化操作。

需要注意以下幾點:

  1. @PostConstruct 只能用在方法上面,而不能用在屬性或構(gòu)造函數(shù)上。
  2. 一個類中可以有多個使用 @PostConstruct 注解的方法,但執(zhí)行順序并不是固定的。
  3. @PostConstruct 注解的方法在本類中必須是無參數(shù)的,如果有參數(shù),那么這個方法不會被執(zhí)行。
  4. @PostConstruct 注解的方法在實現(xiàn)上可以使用任意修飾符。

假設(shè)我們有一個需要初始化數(shù)據(jù)的類:

public class InitService {
 
    private List<String> data;
 
    public InitService() {
        this.data = Arrays.asList("A", "B", "C");
    }
 
    @PostConstruct
    public void init() {
        data.add("D");
    }
 
    public List<String> getData() {
        return this.data;
    }
}

當我們實例化 InitService 時,構(gòu)造函數(shù)會為 data 屬性賦初值,而 @PostConstruct 注解的 init 方法會在 Spring 容器實例化完 InitService 后被執(zhí)行,將 “D” 添加到 data 列表中。所以當我們調(diào)用 getData() 方法時,返回的列表應(yīng)該是 [A, B, C, D]。

接下來看看 @Autowired 和@PostConstruct 的具體執(zhí)行順序

@Service
public class TestA {
    static {
        System.out.println("staticA");
    }
    @Autowired
    private TestB testB;
 
    public TestA() {
        System.out.println("這是TestA 的構(gòu)造方法");
    }
 
    @PostConstruct
    private void init() {
        System.out.println("這是TestA的 init 方法");
        testB.test();
    }
}
@Service
public class TestB {
    static {
        System.out.println("staticB");
    }
    @PostConstruct
    private void init() {
        System.out.println("這是TestB的init 方法");
    }
 
    public TestB() {
        System.out.println("這是TestB的構(gòu)造方法");
    }
 
    void test() {
        System.out.println("這是TestB的test方法");
    }
}

構(gòu)造方法:在對象初始化時執(zhí)行。執(zhí)行順序在static靜態(tài)代碼塊之后。

服務(wù)啟動后,輸出結(jié)果如下:

staticA
這是TestA 的構(gòu)造方法
staticB
這是TestB的構(gòu)造方法
這是TestB的init 方法
這是TestA的 init 方法
這是TestB的test方法

結(jié)論為:等@Autowired注入后,在執(zhí)行@PostConstruct注解的方法。

方式四:靜態(tài)代碼塊

static靜態(tài)代碼塊,在類加載的時候即自動執(zhí)行。

使用的static靜態(tài)代碼塊,實現(xiàn)原理為@Component + static代碼塊, spring boot項目在啟動過程中,會掃描@Component 并初始化相應(yīng)的類,類的初始化過程會運行靜態(tài)代碼塊。

@Component
public class WordInitConfig {
    static {
        WordSegmenter.segWithStopWords("初始化分詞");
    }
}

所以得到結(jié)論

static>constructer>@Autowired>@PostConstruct>ApplicationRunner>CommandLineRunner

到此這篇關(guān)于SpringBoot啟動時執(zhí)行初始化操作的幾種方式的文章就介紹到這了,更多相關(guān)SpringBoot執(zhí)行初始化操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 避免sql注入_動力節(jié)點Java學院整理

    避免sql注入_動力節(jié)點Java學院整理

    這篇文章主要介紹了避免sql注入,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 詳解java枚舉用法及實例

    詳解java枚舉用法及實例

    這篇文章主要介紹了Java枚舉詳解及使用實例,本文直接給出實例代碼,需要的朋友可以參考下
    2017-04-04
  • Mybatis批量新增的三種實現(xiàn)方式

    Mybatis批量新增的三種實現(xiàn)方式

    文章講述了在Java中進行批量操作的最佳實踐,包括使用MyBatis的ExecutorType.BATCH模式,作者建議根據(jù)實際需求選擇是否進行批量操作,因為批量操作并不總是能提升性能,且有副作用,如無法獲取自增ID等
    2024-12-12
  • 入門JDK集合之HashMap解析

    入門JDK集合之HashMap解析

    HashMap---基于哈希表的 Map 接口的實現(xiàn)。此實現(xiàn)提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同
    2021-06-06
  • 完美解決docx4j變量替換的問題

    完美解決docx4j變量替換的問題

    這篇文章主要介紹了完美解決docx4j變量替換的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Spring中的事件監(jiān)聽器使用學習記錄

    Spring中的事件監(jiān)聽器使用學習記錄

    Spring框架中的事件監(jiān)聽機制是一種設(shè)計模式,它允許你定義和觸發(fā)事件,同時允許其他組件監(jiān)聽這些事件并在事件發(fā)生時作出響應(yīng),這篇文章主要介紹了Spring中的事件監(jiān)聽器使用學習,需要的朋友可以參考下
    2024-07-07
  • 解決程序啟動報錯org.springframework.context.ApplicationContextException: Unable to start web server問題

    解決程序啟動報錯org.springframework.context.ApplicationContextExcept

    文章描述了一個Spring Boot項目在不同環(huán)境下啟動時出現(xiàn)差異的問題,通過分析報錯信息,發(fā)現(xiàn)是由于導入`spring-boot-starter-tomcat`依賴時定義的scope導致的配置問題,調(diào)整依賴導入配置后,解決了啟動錯誤
    2024-11-11
  • IDEA 中 maven 的 Lifecycle 和Plugins 的區(qū)別

    IDEA 中 maven 的 Lifecycle 和Plugins&n

    IDEA 主界面右側(cè) Maven 標簽欄有同樣的命令,比如 install,既在 Plugins 中存在,也在 Lifecycle中存在,到底選哪個?二者又有什么區(qū)別呢?下面小編給大家介紹下IDEA 中 maven 的 Lifecycle 和Plugins 的區(qū)別,感興趣的朋友一起看看吧
    2023-03-03
  • SpringBoot如何使用ApplicationContext獲取bean對象

    SpringBoot如何使用ApplicationContext獲取bean對象

    這篇文章主要介紹了SpringBoot 如何使用ApplicationContext獲取bean對象,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring Boot教程之利用ActiveMQ實現(xiàn)延遲消息

    Spring Boot教程之利用ActiveMQ實現(xiàn)延遲消息

    這篇文章主要給大家介紹了關(guān)于Spring Boot教程之利用ActiveMQ實現(xiàn)延遲消息的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring Boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-11-11

最新評論