最新国产好看的视频,伊人天堂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ì)說(shuō)明和最佳實(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ù)庫(kù)數(shù)據(jù)
        userRepository.save(new User("admin", "admin@example.com"));
        System.out.println("數(shù)據(jù)庫(kù)初始化完成");
    }
}

特點(diǎn):

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

2. ApplicationRunner 接口

@Component
@Order(2)
public class CacheWarmup implements ApplicationRunner {
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 更豐富的參數(shù)訪問(wèn)方式
        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ù)訪問(wèn)(ApplicationArguments)
  • 同樣支持@Order排序

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

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

@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),可以開始處理請(qǐ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ù)庫(kù)連接失敗");
        }
        System.out.println("系統(tǒng)驗(yàn)證通過(guò)");
    }
}

特點(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");
    }
}

注冊(cè)方式:

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

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

2.或通過(guò)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)備完成");
    }
    
    // 其他生命周期方法...
}

注冊(cè)方式:

在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)境測(cè)試數(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ī)適用場(chǎng)景順序控制訪問(wèn)Spring上下文
ApplicationContextInitializer最早階段環(huán)境準(zhǔn)備無(wú)有限訪問(wèn)
@PostConstructBean初始化單個(gè)Bean初始化無(wú)完全訪問(wèn)
ApplicationRunner啟動(dòng)中期通用初始化支持完全訪問(wèn)
CommandLineRunner啟動(dòng)中期命令行相關(guān)初始化支持完全訪問(wèn)
ApplicationReadyEvent最后階段安全的后啟動(dòng)操作無(wú)完全訪問(wèn)

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

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

避免事項(xiàng):

  • 不要在啟動(dòng)時(shí)執(zhí)行長(zhǎng)時(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);
                }
            });
    }
}

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

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

相關(guān)文章

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

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

    本文介紹了兩種防止SpringBoot應(yīng)用中表單重復(fù)提交的方法:第一種是使用Redis來(lái)實(shí)現(xiàn),通過(guò)設(shè)置鍵值對(duì)和檢查唯一標(biāo)識(shí)來(lái)防止重復(fù)提交;第二種是使用SpringAOP,通過(guò)創(chuàng)建切面和自定義注解來(lái)統(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í)每刻訪問(wèn)的流量,或者是我們數(shù)據(jù)庫(kù)的訪問(wèn)狀態(tài)等等,這時(shí)候就需要Actuator了,需要的朋友可以參考下
    2023-09-09
  • eclipse創(chuàng)建項(xiàng)目沒(méi)有dynamic web的解決方法

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

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

    Spring整合redis的操作代碼

    這篇文章主要介紹了Spring整合redis的操作代碼,本文通過(guò)實(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的使用,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-09-09
  • 詳解Java單例模式的實(shí)現(xiàn)與原理剖析

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

    單例模式是Java中最簡(jiǎn)單的設(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,接下來(lái)通過(guò)本文給大家介紹JDK8中String的intern()方法詳細(xì)解讀,需要的朋友可以參考下
    2022-09-09
  • mybatis如何通過(guò)接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行詳解

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

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

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

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

最新評(píng)論

沁阳市| 什邡市| 监利县| 繁峙县| 柘荣县| 义乌市| 通州市| 晋中市| 中宁县| 老河口市| 沧源| 北票市| 高雄县| 九龙坡区| 永新县| 曲沃县| 武山县| 兴业县| 汶川县| 仪征市| 金沙县| 丽水市| 平安县| 平凉市| 乌拉特前旗| 武清区| 东明县| 额尔古纳市| 荣昌县| 安新县| 宾阳县| 桦川县| 东平县| 巴塘县| 鄯善县| 西丰县| 清丰县| 宾阳县| 保山市| 和田县| 盐山县|