欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot啟動(dòng)后自動(dòng)執(zhí)行初始化任務(wù)的五種方法

 更新時(shí)間:2025年04月10日 09:44:12   作者:浪浪山老周  
在 Spring Boot 開(kāi)發(fā)中,我們經(jīng)常需要在應(yīng)用啟動(dòng)后立即執(zhí)行初始化任務(wù),本文將深度解析 ??5 種主流實(shí)現(xiàn)方案??,大家可以根據(jù)自己的需求自行選擇

導(dǎo)語(yǔ)??

在 Spring Boot 開(kāi)發(fā)中,我們經(jīng)常需要在應(yīng)用啟動(dòng)后立即執(zhí)行初始化任務(wù)(如加載配置、預(yù)熱緩存、啟動(dòng)定時(shí)任務(wù))。本文將深度解析 ??5 種主流實(shí)現(xiàn)方案??,包含完整代碼示例、執(zhí)行順序控制技巧和避坑指南!

一、為什么需要啟動(dòng)后自動(dòng)執(zhí)行方法

典型使用場(chǎng)景

場(chǎng)景類型具體案例技術(shù)價(jià)值
數(shù)據(jù)初始化 ??加載字典數(shù)據(jù)到內(nèi)存提升接口響應(yīng)速度
定時(shí)任務(wù)啟動(dòng) ??啟動(dòng)分布式任務(wù)調(diào)度確保任務(wù)在服務(wù)就緒后執(zhí)行
?? 資源預(yù)加載??預(yù)熱 Redis 緩存避免冷啟動(dòng)導(dǎo)致的性能波動(dòng)
?? 參數(shù)校驗(yàn)??檢查必要配置項(xiàng)是否存在增強(qiáng)系統(tǒng)健壯性
?? 第三方服務(wù)注冊(cè)??向服務(wù)注冊(cè)中心注冊(cè)實(shí)例保障微服務(wù)可用性

二、六大實(shí)現(xiàn)方案全解析

方案 1:@PostConstruct(簡(jiǎn)單初始化)

@Service
public class CacheInitializer {
    
    @PostConstruct
    public void init() {
        // 在 Bean 初始化完成后執(zhí)行
        loadAllConfigToCache();
        System.out.println("字典數(shù)據(jù)加載完成");
    }
}

??特點(diǎn)??:

  • 執(zhí)行時(shí)機(jī):依賴注入完成后立即執(zhí)行
  • 適用場(chǎng)景:?jiǎn)?Bean 的簡(jiǎn)單初始化
  • 注意:無(wú)法處理跨 Bean 依賴

方案 2:ApplicationRunner(參數(shù)解析增強(qiáng))

java
@Component
@Order(1) // 控制執(zhí)行順序
public class StartupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        // 解析命令行參數(shù)
        boolean force = args.containsOption("force");
        String configFile = args.getOptionValues("config").get(0);
        
        // 執(zhí)行初始化邏輯
        System.out.println("使用參數(shù)啟動(dòng):force="+force+", configFile="+configFile);
    }
}

??優(yōu)勢(shì)??:

  • 支持命令行參數(shù)解析
  • 天然支持 @Order 排序

方案 3:ApplicationListener

@Component
public class ApplicationReadyListener {
    
    @EventListener(ApplicationReadyEvent.class)
    public void onApplicationReady() {
        // 確保所有 Bean 初始化完成
        System.out.println("所有組件就緒,執(zhí)行最終初始化");
    }
}

??特殊價(jià)值??:

  • 可監(jiān)聽(tīng)多個(gè)應(yīng)用事件(如 ApplicationStartingEvent)
  • 適合需要延遲執(zhí)行的場(chǎng)景

方案 4:CommandLineRunner(基礎(chǔ)參數(shù)處理)

@Component
public class ConfigLoader implements CommandLineRunner {
    
    @Override
    public void run(String... args) {
        // 處理原始命令行參數(shù)
        System.out.println("原始參數(shù):"+Arrays.toString(args));
    }
}

適用場(chǎng)景??: 僅需處理字符串參數(shù)的場(chǎng)景

方案 5:自定義監(jiān)聽(tīng)器(復(fù)雜流程控制)

@Component
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (event.getApplicationContext().getParent() == null) {
            // 只在根上下文初始化時(shí)執(zhí)行
            System.out.println("根上下文初始化完成");
        }
    }
}

高級(jí)用法??:

  • 防止多次觸發(fā)(通過(guò)上下文判斷)
  • 結(jié)合 @Async 實(shí)現(xiàn)異步初始化

方案 6:@Scheduled 定時(shí)啟動(dòng)(延遲執(zhí)行)

@Component
@EnableScheduling
public class DelayedInitializer {
    
    @Scheduled(fixedDelay = 5000) // 首次延遲5秒后執(zhí)行
    public void delayedInit() {
        System.out.println("延遲初始化任務(wù)執(zhí)行");
    }
}

??特殊場(chǎng)景??: 需要延遲執(zhí)行的初始化任務(wù)

三、方案對(duì)比決策矩陣

方案執(zhí)行時(shí)機(jī)參數(shù)支持執(zhí)行順序適用復(fù)雜度
@PostConstructBean初始化后無(wú)無(wú)
ApplicationRunner應(yīng)用啟動(dòng)完成解析參數(shù)支持★★★☆☆
ApplicationListener應(yīng)用事件觸發(fā)無(wú)需手動(dòng)★★★★☆
@Scheduled定時(shí)觸發(fā)無(wú)無(wú)★★☆☆☆

四、完整落地流程

步驟 1:創(chuàng)建初始化 Service

@Service
public class StartupService {
    
    public void initConfig() {
        // 加載配置邏輯
    }
    
    public void warmUpCache() {
        // 緩存預(yù)熱邏輯
    }
}

步驟 2:選擇執(zhí)行方案(以 ApplicationRunner 為例)

@Component
@Order(1)
public class StartupRunner implements ApplicationRunner {
    
    private final StartupService startupService;
    
    public StartupRunner(StartupService startupService) {
        this.startupService = startupService;
    }

    @Override
    public void run(ApplicationArguments args) {
        startupService.initConfig();
        startupService.warmUpCache();
    }
}

步驟 3:配置執(zhí)行順序(多初始化任務(wù)時(shí))

@Component
@Order(2)
public class SecondaryInitializer implements CommandLineRunner {
    // 次級(jí)初始化任務(wù)
}

五、避坑指南與最佳實(shí)踐

1. 循環(huán)依賴陷阱

// 錯(cuò)誤示例:A 依賴 B,B 依賴 A
@Service
public class AService {
    private final BService bService;
    
    public AService(BService bService) {
        this.bService = bService;
    }
    
    @PostConstruct
    public void init() {
        bService.doSomething(); // 觸發(fā)循環(huán)依賴
    }
}

解決方案??: 使用 @Lazy 延遲加載

2. 異步執(zhí)行配置

@EnableAsync
@Configuration
public class AsyncConfig {
    
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setQueueCapacity(100);
        return executor;
    }
}

???????// 在方法上添加異步執(zhí)行
@Async
public void asyncInit() {
    // 異步初始化邏輯
}

3. 執(zhí)行順序控制

@Component
@Order(1) // 數(shù)字越小優(yōu)先級(jí)越高
public class FirstInitializer implements ApplicationRunner {}

@Component
@Order(2)
public class SecondInitializer implements ApplicationRunner {}

六、生產(chǎn)環(huán)境驗(yàn)證方案

1. 單元測(cè)試

@SpringBootTest
class StartupTest {
    
    @Autowired
    private StartupService startupService;
    
    @Test
    void testInitSequence() {
        // 驗(yàn)證初始化順序
        verifyOrder(startupService::initConfig, startupService::warmUpCache);
    }
}

2. 日志監(jiān)控

2025-04-09 09:00:00.000  INFO 12345 --- [           main] c.e.demo.StartupRunner                 : === 應(yīng)用啟動(dòng)初始化開(kāi)始 ===
2025-04-09 09:00:00.100  INFO 12345 --- [           main] c.e.demo.CacheInitializer              : 字典數(shù)據(jù)加載完成(耗時(shí)85ms)
2025-04-09 09:00:00.200  INFO 12345 --- [           main] c.e.demo.StartupRunner                 : === 所有初始化任務(wù)完成 ===

七、擴(kuò)展場(chǎng)景方案

1. 分布式鎖控制(防重復(fù)執(zhí)行)

@PostConstruct
public void distributedInit() {
    RLock lock = redissonClient.getLock("startup:init");
    if (lock.tryLock(0, 60, TimeUnit.SECONDS)) {
        try {
            // 執(zhí)行初始化
        } finally {
            lock.unlock();
        }
    }
}

2. 健康檢查聯(lián)動(dòng)

@EventListener(ApplicationReadyEvent.class)
public void healthCheck() {
    HealthIndicator indicator = context.getBean(HealthIndicator.class);
    if (!indicator.health().getStatus().equals(Status.UP)) {
        throw new RuntimeException("依賴服務(wù)未就緒");
    }
}

八、總結(jié)與選擇建議

需求場(chǎng)景推薦方案
簡(jiǎn)單初始化@PostConstruct
需要參數(shù)處理ApplicationRunner
需要監(jiān)聽(tīng)?wèi)?yīng)用狀態(tài)ApplicationListener
延遲執(zhí)行@Scheduled
復(fù)雜初始化流程自定義監(jiān)聽(tīng)器 + 異步執(zhí)行

以上就是SpringBoot啟動(dòng)后自動(dòng)執(zhí)行初始化任務(wù)的五種方法的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot啟動(dòng)后初始化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java日志框架之logback使用詳解

    Java日志框架之logback使用詳解

    這篇文章主要介紹了Java日志框架之logback使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot使用Redisson實(shí)現(xiàn)延遲執(zhí)行的完整示例

    SpringBoot使用Redisson實(shí)現(xiàn)延遲執(zhí)行的完整示例

    這篇文章主要介紹了SpringBoot使用Redisson實(shí)現(xiàn)延遲執(zhí)行的完整示例,文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-06-06
  • 使用Spring-Retry解決Spring Boot應(yīng)用程序中的重試問(wèn)題

    使用Spring-Retry解決Spring Boot應(yīng)用程序中的重試問(wèn)題

    重試的使用場(chǎng)景比較多,比如調(diào)用遠(yuǎn)程服務(wù)時(shí),由于網(wǎng)絡(luò)或者服務(wù)端響應(yīng)慢導(dǎo)致調(diào)用超時(shí),此時(shí)可以多重試幾次。用定時(shí)任務(wù)也可以實(shí)現(xiàn)重試的效果,但比較麻煩,用Spring Retry的話一個(gè)注解搞定所有,感興趣的可以了解一下
    2023-04-04
  • Java窗體動(dòng)態(tài)加載磁盤文件的實(shí)現(xiàn)方法

    Java窗體動(dòng)態(tài)加載磁盤文件的實(shí)現(xiàn)方法

    這篇文章主要介紹了Java窗體動(dòng)態(tài)加載磁盤文件的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2014-03-03
  • 基于swing開(kāi)發(fā)彈幕播放器

    基于swing開(kāi)發(fā)彈幕播放器

    這篇文章主要為大家詳細(xì)介紹了基于swing實(shí)現(xiàn)彈幕播放器的開(kāi)發(fā)過(guò)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Java調(diào)用Pytorch模型實(shí)現(xiàn)圖像識(shí)別

    Java調(diào)用Pytorch模型實(shí)現(xiàn)圖像識(shí)別

    這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用Pytorch實(shí)現(xiàn)圖像識(shí)別功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06
  • 詳解Java構(gòu)建樹(shù)結(jié)構(gòu)的公共方法

    詳解Java構(gòu)建樹(shù)結(jié)構(gòu)的公共方法

    本文主要介紹了詳解Java構(gòu)建樹(shù)結(jié)構(gòu)的公共方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • springboot2.5.2與 flowable6.6.0整合流程引擎應(yīng)用分析

    springboot2.5.2與 flowable6.6.0整合流程引擎應(yīng)用分析

    這篇文章主要介紹了springboot2.5.2與 flowable6.6.0整合流程引擎應(yīng)用分析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • Java使用JSON實(shí)現(xiàn)處理中文亂碼和Date格式

    Java使用JSON實(shí)現(xiàn)處理中文亂碼和Date格式

    這篇文章主要為大家詳細(xì)介紹了Java如何在項(xiàng)目中使用JSON實(shí)現(xiàn)處理中文亂碼和Date格式的功能,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下
    2023-06-06
  • Java 替換word文檔文字并指定位置插入圖片

    Java 替換word文檔文字并指定位置插入圖片

    這篇文章主要介紹了Java 替換word文檔文字,指定位置插入圖片功能,本文通過(guò)實(shí)例代碼給大家講解,需要的朋友可以參考下
    2018-02-02

最新評(píng)論