最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

場(chǎng)景

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

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

CommandLineRunner是Spring提供的接口,定義了一個(gè)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:"+"{}"+"接口實(shí)現(xiàn)方式重寫");
    }
}

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

若有多組初始化操作,則每一組操作都要定義一個(gè)CommandLineRunner派生類并實(shí)現(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");
    }
}

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

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

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

ApplicationRunner接口與CommandLineRunner接口類似,都需要實(shí)現(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("項(xiàng)目啟動(dòng)初始化");
    }
}

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

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

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

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

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

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

初始化順序

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

擴(kuò)展

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

需要注意以下幾點(diǎn):

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

假設(shè)我們有一個(gè)需要初始化數(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;
    }
}

當(dāng)我們實(shí)例化 InitService 時(shí),構(gòu)造函數(shù)會(huì)為 data 屬性賦初值,而 @PostConstruct 注解的 init 方法會(huì)在 Spring 容器實(shí)例化完 InitService 后被執(zhí)行,將 “D” 添加到 data 列表中。所以當(dāng)我們調(diào)用 getData() 方法時(shí),返回的列表應(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)造方法:在對(duì)象初始化時(shí)執(zhí)行。執(zhí)行順序在static靜態(tài)代碼塊之后。

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

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

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

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

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

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

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

所以得到結(jié)論

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

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

相關(guān)文章

  • Java源碼解析之接口Collection

    Java源碼解析之接口Collection

    Collection是List、Queue和set的超集,它直接繼承于Iterable,也就是說所有的Collection集合類都支持foreach循環(huán).除此之外呢,Collection也是面向接口編程的典范,它可以在多種實(shí)現(xiàn)類間轉(zhuǎn)換,這就是面向?qū)ο缶幊痰膮柡χ?接下來就隨著小編一起去看看吧,需要的朋友可以參考下
    2021-05-05
  • 解決IDEA修改 .vmoptions 文件后導(dǎo)致無法啟動(dòng)的問題

    解決IDEA修改 .vmoptions 文件后導(dǎo)致無法啟動(dòng)的問題

    這篇文章主要介紹了解決IDEA修改 .vmoptions 文件后導(dǎo)致無法啟動(dòng)的問題,需要的朋友可以參考下
    2020-12-12
  • SpringBoot配置文件properties和yml的實(shí)現(xiàn)

    SpringBoot配置文件properties和yml的實(shí)現(xiàn)

    本文主要介紹了SpringBoot配置文件properties和yml的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Java基于final修飾數(shù)據(jù)過程解析

    Java基于final修飾數(shù)據(jù)過程解析

    這篇文章主要介紹了Java基于final修飾數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot接受參數(shù)相關(guān)注解方式

    SpringBoot接受參數(shù)相關(guān)注解方式

    SpringBoot接受參數(shù)的注解包括@PathVariable、@RequestHeader、@RequestParameter、@CookieValue、@RequestBody、@RequestAttribute和@SessionAttribute等,每個(gè)注解都有詳細(xì)的使用方法和示例代碼
    2024-12-12
  • Java基于Lock的生產(chǎn)者消費(fèi)者模型示例

    Java基于Lock的生產(chǎn)者消費(fèi)者模型示例

    這篇文章主要介紹了Java基于Lock的生產(chǎn)者消費(fèi)者模型,結(jié)合實(shí)例形式分析了java基于鎖機(jī)制的生產(chǎn)者消費(fèi)者模型相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2018-08-08
  • Java借助Spire.PDF?for?Java高效實(shí)現(xiàn)PDF自動(dòng)排版

    Java借助Spire.PDF?for?Java高效實(shí)現(xiàn)PDF自動(dòng)排版

    在?Java?開發(fā)中,處理?PDF?文檔的生成與編輯是常見的需求,本文將深入探討如何利用?Java?高效準(zhǔn)確地設(shè)置?PDF?中的文字對(duì)齊方式,感興趣的小伙伴可以了解下
    2026-01-01
  • Java最常用的6個(gè)簡(jiǎn)單的計(jì)算題

    Java最常用的6個(gè)簡(jiǎn)單的計(jì)算題

    本篇文章給大家整理的在JAVA中最常用到的簡(jiǎn)單的計(jì)算題,對(duì)此有興趣的朋友可以測(cè)試參考下。
    2018-02-02
  • SpringBoot+Caffeine+Redis實(shí)現(xiàn)多級(jí)緩存的方法

    SpringBoot+Caffeine+Redis實(shí)現(xiàn)多級(jí)緩存的方法

    多級(jí)緩存是指在系統(tǒng)中部署多層功能互補(bǔ)的緩存組件,讓請(qǐng)求按照預(yù)設(shè)順序依次訪問各層緩存,僅當(dāng)所有緩存層均未命中時(shí),才訪問底層數(shù)據(jù)庫的架構(gòu)模式,這篇文章主要介紹了SpringBoot+Caffeine+Redis實(shí)現(xiàn)多級(jí)緩存的方法,需要的朋友可以參考下
    2026-02-02
  • MyBatis-Plus高效開發(fā)實(shí)戰(zhàn)指南

    MyBatis-Plus高效開發(fā)實(shí)戰(zhàn)指南

    MyBatis-Plus(簡(jiǎn)稱?MP)是?個(gè)MyBatis的增強(qiáng)工具,在MyBatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā),本文介紹MyBatis-Plus高效開發(fā)全攻略,感興趣的朋友跟隨小編一起看看吧
    2026-03-03

最新評(píng)論

临高县| 临沭县| 怀宁县| 翁牛特旗| 隆化县| 天津市| 西乌| 阳西县| 衢州市| 马龙县| 清苑县| 托里县| 延津县| 措美县| 嘉定区| 平阳县| 合水县| 香格里拉县| 沂水县| 古蔺县| 衢州市| 咸阳市| 临颍县| 乌兰浩特市| 泰宁县| 开江县| 兴隆县| 十堰市| 临沭县| 岚皋县| 调兵山市| 阳东县| 来宾市| 若羌县| 景洪市| 鲁甸县| 长白| 广东省| 丰都县| 凤阳县| 涟源市|