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

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

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

導(dǎo)語??

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

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

典型使用場景

場景類型具體案例技術(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ù)注冊??向服務(wù)注冊中心注冊實(shí)例保障微服務(wù)可用性

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

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

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

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

  • 執(zhí)行時(shí)機(jī):依賴注入完成后立即執(zhí)行
  • 適用場景:單 Bean 的簡單初始化
  • 注意:無法處理跨 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ù)解析
  • 天然支持 @Order 排序

方案 3:ApplicationListener

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

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

  • 可監(jiān)聽多個(gè)應(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)聽器(復(fù)雜流程控制)

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

高級用法??:

  • 防止多次觸發(fā)(通過上下文判斷)
  • 結(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í)行");
    }
}

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

三、方案對比決策矩陣

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

四、完整落地流程

步驟 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 {
    // 次級初始化任務(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)先級越高
public class FirstInitializer implements ApplicationRunner {}

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

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

1. 單元測試

@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)初始化開始 ===
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ò)展場景方案

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é)與選擇建議

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

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

相關(guān)文章

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

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

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

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

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

    Java Idea TranslationPlugin翻譯插件使用解析

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

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

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

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

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

    MyBatis全局配置文件詳解

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

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

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

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

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

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

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

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

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

最新評論

宁陕县| 平和县| 天峨县| 桂阳县| 鲁甸县| 新邵县| 马山县| 衡南县| 靖宇县| 静乐县| 额济纳旗| 瑞昌市| 东光县| 广南县| 无棣县| 邵阳市| 新巴尔虎右旗| 东丽区| 潮安县| 靖安县| 安国市| 美姑县| 图木舒克市| 桐庐县| 得荣县| 通州区| 双鸭山市| 平安县| 大兴区| 收藏| 永嘉县| 乌拉特中旗| 庄浪县| 龙里县| 阿图什市| 焦作市| 汤原县| 抚宁县| 嘉定区| 涞源县| 青海省|