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

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

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

導語??

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

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

典型使用場景

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

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

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

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

??特點??:

  • 執(zhí)行時機:依賴注入完成后立即執(zhí)行
  • 適用場景:單 Bean 的簡單初始化
  • 注意:無法處理跨 Bean 依賴

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

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ù)啟動:force="+force+", configFile="+configFile);
    }
}

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

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

方案 3:ApplicationListener

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

??特殊價值??:

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

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

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

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

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

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

高級用法??:

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

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

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

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

三、方案對比決策矩陣

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

四、完整落地流程

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

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

步驟 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ù)時)

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

五、避坑指南與最佳實踐

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

// 錯誤示例: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)先級越高
public class FirstInitializer implements ApplicationRunner {}

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

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

1. 單元測試

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

2. 日志監(jiān)控

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

七、擴展場景方案

1. 分布式鎖控制(防重復執(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)動

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

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

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

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

相關(guān)文章

  • 如何使用NSSM將jar包打成Windows服務(wù)

    如何使用NSSM將jar包打成Windows服務(wù)

    這篇文章主要介紹了如何使用NSSM將jar包打成Windows服務(wù),本文通過圖文并茂的形式給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Spring JPA聯(lián)表查詢之OneToMany源碼解析

    Spring JPA聯(lián)表查詢之OneToMany源碼解析

    這篇文章主要為大家介紹了Spring JPA聯(lián)表查詢之OneToMany源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Java Idea TranslationPlugin翻譯插件使用解析

    Java Idea TranslationPlugin翻譯插件使用解析

    這篇文章主要介紹了Java Idea TranslationPlugin翻譯插件使用解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • Spring Data JPA調(diào)用存儲過程實例代碼

    Spring Data JPA調(diào)用存儲過程實例代碼

    本篇文章主要介紹了Spring Data JPA調(diào)用存儲過程實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • Java比較集合是否相等的技巧分享

    Java比較集合是否相等的技巧分享

    集合使我們開發(fā)過程中非常用到的,要說最常用的,非List莫屬,那么當我們想要比較兩個List是否相等的時候,應(yīng)該怎么處理呢?本文將介紹幾個小技巧來處理,需要的朋友可以參考下
    2025-06-06
  • MyBatis全局配置文件詳解

    MyBatis全局配置文件詳解

    這篇文章主要介紹了mybatis 加載配置文件的方法,通過實例代碼給大家介紹了mybatis 加載配置文件的兩種方式,需要的朋友可以參考下
    2021-07-07
  • java如何實現(xiàn)自動生成數(shù)據(jù)庫設(shè)計文檔

    java如何實現(xiàn)自動生成數(shù)據(jù)庫設(shè)計文檔

    以前我們還需要手寫數(shù)據(jù)庫設(shè)計文檔、現(xiàn)在可以通過引入screw核心包來實現(xiàn)Java?數(shù)據(jù)庫文檔一鍵生成。本文將具體介紹一下如何通過java自動生成數(shù)據(jù)庫設(shè)計文檔,需要的朋友可以參考下
    2021-11-11
  • Java使用枚舉實現(xiàn)狀態(tài)機的方法詳解

    Java使用枚舉實現(xiàn)狀態(tài)機的方法詳解

    這篇文章主要介紹了Java使用枚舉實現(xiàn)狀態(tài)機的方法詳解,枚舉類型很適合用來實現(xiàn)狀態(tài)機,狀態(tài)機可以處于有限數(shù)量的特定狀態(tài),它們通常根據(jù)輸入,從一個狀態(tài)移動到下一個狀態(tài),但同時也會存在瞬態(tài),需要的朋友可以參考下
    2023-11-11
  • spring AOP自定義注解方式實現(xiàn)日志管理的實例講解

    spring AOP自定義注解方式實現(xiàn)日志管理的實例講解

    下面小編就為大家分享一篇spring AOP自定義注解方式實現(xiàn)日志管理的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 基于SpringBoot+Mybatis實現(xiàn)Mysql分表

    基于SpringBoot+Mybatis實現(xiàn)Mysql分表

    這篇文章主要為大家詳細介紹了基于SpringBoot+Mybatis實現(xiàn)Mysql分表的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-04-04

最新評論

迁安市| 黎平县| 信阳市| 柳林县| 宜宾县| 芮城县| 迁西县| 沾化县| 南川市| 全南县| 富源县| 龙山县| 潼南县| 望谟县| 江阴市| 颍上县| 石泉县| 尖扎县| 安阳县| 日喀则市| 朝阳区| 织金县| 二手房| 邓州市| 靖江市| 阜平县| 铅山县| 永胜县| 庆元县| 五大连池市| 巩留县| 府谷县| 德庆县| 蓬溪县| 专栏| 平潭县| 文昌市| 井陉县| 钟祥市| 东平县| 浮山县|