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

SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行特定代碼的完整指南

 更新時(shí)間:2025年04月27日 09:19:16   作者:北辰alk  
Spring?Boot?提供了多種靈活的方式在應(yīng)用啟動(dòng)時(shí)執(zhí)行初始化代碼,以下是所有可行方法的詳細(xì)說明和最佳實(shí)踐,大家可以根據(jù)自己的需求進(jìn)行選擇

一、應(yīng)用生命周期回調(diào)方式

1. CommandLineRunner 接口

@Component
@Order(1) // 可選,定義執(zhí)行順序
public class DatabaseInitializer implements CommandLineRunner {
    
    private final UserRepository userRepository;
    
    public DatabaseInitializer(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    @Override
    public void run(String... args) throws Exception {
        // 初始化數(shù)據(jù)庫數(shù)據(jù)
        userRepository.save(new User("admin", "admin@example.com"));
        System.out.println("數(shù)據(jù)庫初始化完成");
    }
}

特點(diǎn):

  • 在所有ApplicationReadyEvent之前執(zhí)行
  • 可以訪問命令行參數(shù)
  • 支持多實(shí)例,通過@Order控制順序

2. ApplicationRunner 接口

@Component
@Order(2)
public class CacheWarmup implements ApplicationRunner {
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 更豐富的參數(shù)訪問方式
        System.out.println("源參數(shù): " + args.getSourceArgs());
        System.out.println("選項(xiàng)參數(shù): " + args.getOptionNames());
        
        // 預(yù)熱緩存邏輯
        System.out.println("緩存預(yù)熱完成");
    }
}

與CommandLineRunner區(qū)別:

  • 提供更結(jié)構(gòu)化的參數(shù)訪問(ApplicationArguments)
  • 同樣支持@Order排序

二、Spring事件監(jiān)聽方式

1. 監(jiān)聽特定生命周期事件

@Component
public class StartupEventListener {
    
    // 在環(huán)境準(zhǔn)備完成后執(zhí)行
    @EventListener(ApplicationEnvironmentPreparedEvent.class)
    public void handleEnvPrepared(ApplicationEnvironmentPreparedEvent event) {
        ConfigurableEnvironment env = event.getEnvironment();
        System.out.println("當(dāng)前環(huán)境: " + env.getActiveProfiles());
    }
    
    // 在應(yīng)用上下文準(zhǔn)備好后執(zhí)行
    @EventListener(ApplicationContextInitializedEvent.class)
    public void handleContextInit(ApplicationContextInitializedEvent event) {
        System.out.println("應(yīng)用上下文初始化完成");
    }
    
    // 在所有Bean加載完成后執(zhí)行
    @EventListener(ContextRefreshedEvent.class)
    public void handleContextRefresh(ContextRefreshedEvent event) {
        System.out.println("所有Bean已加載");
    }
    
    // 在應(yīng)用完全啟動(dòng)后執(zhí)行(推薦)
    @EventListener(ApplicationReadyEvent.class)
    public void handleAppReady(ApplicationReadyEvent event) {
        System.out.println("應(yīng)用已完全啟動(dòng),可以開始處理請求");
    }
}

2. 事件執(zhí)行順序

三、Bean生命周期回調(diào)

1. @PostConstruct 注解

@Service
public class SystemValidator {
    
    @Autowired
    private HealthCheckService healthCheckService;
    
    @PostConstruct
    public void validateSystem() {
        if (!healthCheckService.isDatabaseConnected()) {
            throw new IllegalStateException("數(shù)據(jù)庫連接失敗");
        }
        System.out.println("系統(tǒng)驗(yàn)證通過");
    }
}

特點(diǎn):

  • 在Bean依賴注入完成后立即執(zhí)行
  • 適用于單個(gè)Bean的初始化
  • 拋出異常會(huì)阻止應(yīng)用啟動(dòng)

2. InitializingBean 接口

@Component
public class NetworkChecker implements InitializingBean {
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("網(wǎng)絡(luò)連接檢查完成");
        // 執(zhí)行網(wǎng)絡(luò)檢查邏輯
    }
}

與@PostConstruct比較:

  • 功能類似,但屬于Spring接口而非JSR-250標(biāo)準(zhǔn)
  • 執(zhí)行時(shí)機(jī)稍晚于@PostConstruct

四、Spring Boot特性擴(kuò)展

1. ApplicationContextInitializer

public class CustomInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 在上下文刷新前執(zhí)行
        System.out.println("應(yīng)用上下文初始化器執(zhí)行");
        // 可以修改環(huán)境配置
        applicationContext.getEnvironment().setActiveProfiles("dev");
    }
}

注冊方式:

1.在META-INF/spring.factories中添加:

org.springframework.context.ApplicationContextInitializer=com.example.CustomInitializer

2.或通過SpringApplication添加:

@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(MyApp.class);
        app.addInitializers(new CustomInitializer());
        app.run(args);
    }
}

2. SpringApplicationRunListener

public class StartupMonitor implements SpringApplicationRunListener {
    
    public StartupMonitor(SpringApplication app, String[] args) {}
    
    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("應(yīng)用開始啟動(dòng)");
    }
    
    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, 
                                  ConfigurableEnvironment environment) {
        System.out.println("環(huán)境準(zhǔn)備完成");
    }
    
    // 其他生命周期方法...
}

注冊方式:

在META-INF/spring.factories中:

org.springframework.boot.SpringApplicationRunListener=com.example.StartupMonitor

五、條件化初始化

1. 基于Profile的初始化

@Profile("dev")
@Component
public class DevDataLoader implements CommandLineRunner {
    
    @Override
    public void run(String... args) {
        System.out.println("加載開發(fā)環(huán)境測試數(shù)據(jù)");
    }
}

2. 基于條件的Bean創(chuàng)建

@Configuration
public class ConditionalInitConfig {
    
    @Bean
    @ConditionalOnProperty(name = "app.init-sample-data", havingValue = "true")
    public CommandLineRunner sampleDataLoader() {
        return args -> System.out.println("加載示例數(shù)據(jù)");
    }
}

六、初始化方法對(duì)比

方法執(zhí)行時(shí)機(jī)適用場景順序控制訪問Spring上下文
ApplicationContextInitializer最早階段環(huán)境準(zhǔn)備有限訪問
@PostConstructBean初始化單個(gè)Bean初始化完全訪問
ApplicationRunner啟動(dòng)中期通用初始化支持完全訪問
CommandLineRunner啟動(dòng)中期命令行相關(guān)初始化支持完全訪問
ApplicationReadyEvent最后階段安全的后啟動(dòng)操作完全訪問

七、最佳實(shí)踐建議

  • 簡單初始化:使用@PostConstruct或InitializingBean
  • 復(fù)雜初始化:使用CommandLineRunner/ApplicationRunner
  • 環(huán)境準(zhǔn)備階段:使用ApplicationContextInitializer
  • 完全啟動(dòng)后操作:監(jiān)聽ApplicationReadyEvent

避免事項(xiàng):

  • 不要在啟動(dòng)時(shí)執(zhí)行長時(shí)間阻塞操作
  • 謹(jǐn)慎處理ContextRefreshedEvent(可能被觸發(fā)多次)
  • 確保初始化代碼是冪等的

八、高級(jí)應(yīng)用示例

1. 異步初始化

@Component
public class AsyncInitializer {
    
    @EventListener(ApplicationReadyEvent.class)
    @Async
    public void asyncInit() {
        System.out.println("異步初始化開始");
        // 執(zhí)行耗時(shí)初始化任務(wù)
        System.out.println("異步初始化完成");
    }
}

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

2. 初始化失敗處理

@Component
public class StartupFailureHandler implements ApplicationListener<ApplicationFailedEvent> {
    
    @Override
    public void onApplicationEvent(ApplicationFailedEvent event) {
        Throwable exception = event.getException();
        System.err.println("應(yīng)用啟動(dòng)失敗: " + exception.getMessage());
        // 發(fā)送警報(bào)或記錄日志
    }
}

3. 多模塊初始化協(xié)調(diào)

public interface StartupTask {
    void execute() throws Exception;
    int getOrder();
}

@Component
public class StartupCoordinator implements ApplicationRunner {
    
    @Autowired
    private List<StartupTask> startupTasks;
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        startupTasks.stream()
            .sorted(Comparator.comparingInt(StartupTask::getOrder))
            .forEach(task -> {
                try {
                    task.execute();
                } catch (Exception e) {
                    throw new StartupException("啟動(dòng)任務(wù)執(zhí)行失敗: " + task.getClass().getName(), e);
                }
            });
    }
}

通過以上多種方式,Spring Boot 提供了非常靈活的啟動(dòng)時(shí)初始化機(jī)制,開發(fā)者可以根據(jù)具體需求選擇最適合的方法來實(shí)現(xiàn)啟動(dòng)時(shí)邏輯執(zhí)行。

以上就是SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行特定代碼的完整指南的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot執(zhí)行特定代碼的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springboot防止表單重復(fù)提交方式

    springboot防止表單重復(fù)提交方式

    本文介紹了兩種防止SpringBoot應(yīng)用中表單重復(fù)提交的方法:第一種是使用Redis來實(shí)現(xiàn),通過設(shè)置鍵值對(duì)和檢查唯一標(biāo)識(shí)來防止重復(fù)提交;第二種是使用SpringAOP,通過創(chuàng)建切面和自定義注解來統(tǒng)一處理防重復(fù)提交,減少重復(fù)代碼并保持業(yè)務(wù)邏輯清晰
    2025-12-12
  • Springboot集成Actuator監(jiān)控功能詳解

    Springboot集成Actuator監(jiān)控功能詳解

    這篇文章主要介紹了Springboot集成Actuator監(jiān)控功能詳解,有時(shí)候我們想要實(shí)時(shí)監(jiān)控我們的應(yīng)用程序的運(yùn)行狀態(tài),比如實(shí)時(shí)顯示一些指標(biāo)數(shù)據(jù),觀察每時(shí)每刻訪問的流量,或者是我們數(shù)據(jù)庫的訪問狀態(tài)等等,這時(shí)候就需要Actuator了,需要的朋友可以參考下
    2023-09-09
  • eclipse創(chuàng)建項(xiàng)目沒有dynamic web的解決方法

    eclipse創(chuàng)建項(xiàng)目沒有dynamic web的解決方法

    最近上課要用到eclipse,要用到Dynamic web project.但是我下載的版本上沒有.接下來就帶大家了解 eclipse創(chuàng)建項(xiàng)目沒有dynamic web的解決方法,文中有非常詳細(xì)的圖文示例,需要的朋友可以參考下
    2021-06-06
  • Spring整合redis的操作代碼

    Spring整合redis的操作代碼

    這篇文章主要介紹了Spring整合redis的操作代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • idea中一鍵自動(dòng)生成序列化serialVersionUID方式

    idea中一鍵自動(dòng)生成序列化serialVersionUID方式

    這篇文章主要介紹了idea中一鍵自動(dòng)生成序列化serialVersionUID方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • java中JDeps命令使用

    java中JDeps命令使用

    jdeps是一個(gè)Java類依賴分析工具,用于分析Java應(yīng)用程序的依賴情況,包括類、包、模塊以及JDK內(nèi)部API的使用,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-09-09
  • 詳解Java單例模式的實(shí)現(xiàn)與原理剖析

    詳解Java單例模式的實(shí)現(xiàn)與原理剖析

    單例模式是Java中最簡單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。本文將詳解單例模式的實(shí)現(xiàn)及原理剖析,需要的可以參考一下
    2022-05-05
  • JDK8中String的intern()方法實(shí)例詳細(xì)解讀

    JDK8中String的intern()方法實(shí)例詳細(xì)解讀

    String字符串在我們?nèi)粘i_發(fā)中最常用的,當(dāng)然還有他的兩個(gè)兄弟StringBuilder和StringBuilder,接下來通過本文給大家介紹JDK8中String的intern()方法詳細(xì)解讀,需要的朋友可以參考下
    2022-09-09
  • mybatis如何通過接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行詳解

    mybatis如何通過接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行詳解

    這篇文章主要給大家介紹了利用mybatis如何通過接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-06-06
  • Java如何獲取HttpServletRequest請求參數(shù)

    Java如何獲取HttpServletRequest請求參數(shù)

    我們常需要接口接收第三方推送的數(shù)據(jù),由于第三方可能不具備開發(fā)能力,我們需要自行解析推送的數(shù)據(jù)格式,通過HttpServletRequest,我們可以解析字符串、JSON、XML以及文件等多種數(shù)據(jù)類型,本文介紹了如何在Java中使用HttpServletRequest獲取請求參數(shù),感興趣的朋友一起看看吧
    2024-11-11

最新評(píng)論

阿城市| 隆德县| 航空| 绥棱县| 无棣县| 云林县| 休宁县| 哈尔滨市| 青神县| 容城县| 巴东县| 澜沧| 云阳县| 廉江市| 阿勒泰市| 平谷区| 依兰县| 高陵县| 商都县| 昆明市| 建瓯市| 夏河县| 凤翔县| 黎川县| 长乐市| 睢宁县| 名山县| 左权县| 电白县| 沙湾县| 彭泽县| 新和县| 巫溪县| 永宁县| 东乌珠穆沁旗| 镇远县| 婺源县| 通许县| 繁昌县| 洛浦县| 二手房|