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

SpringBoot工程啟動時自動執(zhí)行任務實現(xiàn)方式

 更新時間:2025年09月04日 10:08:36   作者:angushine  
在SpringBoot中,推薦通過ApplicationRunner/CommandLineRunner或ApplicationReadyEvent監(jiān)聽實現(xiàn)啟動時自動執(zhí)行MQ任務,確保應用完全就緒,避免依賴未初始化問題,同時需配置連接池、重試機制及多環(huán)境控制,保障系統(tǒng)穩(wěn)定與資源優(yōu)雅關閉

在 Spring Boot 中實現(xiàn)工程啟動時自動執(zhí)行任務(如開始消費 MQ 數(shù)據(jù))有多種可靠的方式。

以下是幾種常用的方法:

1.使用CommandLineRunner或ApplicationRunner接口

2.使用@PostConstruct注解

3.使用ApplicationListener監(jiān)聽ApplicationReadyEvent事件

4.使用@EventListener注解監(jiān)聽應用上下文事件

其中,推薦使用ApplicationRunner或CommandLineRunner,或者監(jiān)聽ApplicationReadyEvent事件,因為此時應用上下文已經(jīng)完全準備好,避免在應用還未完全初始化時就執(zhí)行任務。

推薦實現(xiàn)方案

  1. 使用 ApplicationRunner或 CommandLineRunner(最常用)
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MqConsumerStarter implements ApplicationRunner {

    private final MqConsumerService mqConsumerService;

    public MqConsumerStarter(MqConsumerService mqConsumerService) {
        this.mqConsumerService = mqConsumerService;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 應用啟動后立即執(zhí)行
        mqConsumerService.startConsuming();
    }
}

特點??:

  • 在 ApplicationContext完全加載后執(zhí)行
  • 可以訪問所有 Spring Bean
  • 支持多個 Runner 并指定執(zhí)行順序
  1. 使用 @EventListener監(jiān)聽 ApplicationReadyEvent
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class MqConsumerInitializer {

    private final MqConsumerService mqConsumerService;

    public MqConsumerInitializer(MqConsumerService mqConsumerService) {
        this.mqConsumerService = mqConsumerService;
    }

    @EventListener(ApplicationReadyEvent.class)
    public void onApplicationReady() {
        // 應用完全啟動后執(zhí)行
        mqConsumerService.startConsuming();
    }
}

特點??:

  • 在應用完全就緒后執(zhí)行(包括所有 Runner 執(zhí)行完畢)
  • 確保所有 Bean 已初始化完成
  • 避免在上下文未完全準備好時操作
  1. 使用 SmartLifecycle接口(適合長期運行任務)
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

@Component
public class MqConsumerLifecycle implements SmartLifecycle {

    private final MqConsumerService mqConsumerService;
    private volatile boolean running = false;

    public MqConsumerLifecycle(MqConsumerService mqConsumerService) {
        this.mqConsumerService = mqConsumerService;
    }

    @Override
    public void start() {
        if (!running) {
            mqConsumerService.startConsuming();
            running = true;
        }
    }

    @Override
    public void stop() {
        if (running) {
            mqConsumerService.stopConsuming();
            running = false;
        }
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    @Override
    public int getPhase() {
        return Integer.MAX_VALUE; // 最后啟動
    }
}

特點??:

  • 支持啟動/停止生命周期管理
  • 可以控制啟動順序(通過 getPhase())
  • 適合需要優(yōu)雅關閉的資源

MQ 消費實現(xiàn)示例(RabbitMQ)

  1. 配置 RabbitMQ 監(jiān)聽器
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class RabbitMqConsumer {

    @RabbitListener(queues = "${mq.queue.name}")
    public void handleMessage(String message) {
        System.out.println("Received message: " + message);
        // 處理消息邏輯
    }
}
  1. 啟動時自動創(chuàng)建隊列和綁定
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {

    @Bean
    public Queue myQueue() {
        return new Queue("${mq.queue.name}", true); // 持久化隊列
    }
}
  1. 手動控制消費啟停
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.stereotype.Service;

@Service
public class MqConsumerService {

    private final SimpleMessageListenerContainer container;

    public MqConsumerService(SimpleMessageListenerContainer container) {
        this.container = container;
    }

    public void startConsuming() {
        if (!container.isRunning()) {
            container.start();
        }
    }

    public void stopConsuming() {
        if (container.isRunning()) {
            container.stop();
        }
    }
}

Kafka 消費實現(xiàn)示例

  1. 配置 Kafka 監(jiān)聽器
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

@Component
public class KafkaConsumer {

    @KafkaListener(topics = "${kafka.topic.name}", groupId = "${kafka.group.id}")
    public void listen(String message) {
        System.out.println("Received Message: " + message);
        // 處理消息邏輯
    }
}
  1. 手動控制消費啟停
import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
import org.springframework.stereotype.Service;

@Service
public class KafkaConsumerService {

    private final KafkaListenerEndpointRegistry registry;

    public KafkaConsumerService(KafkaListenerEndpointRegistry registry) {
        this.registry = registry;
    }

    public void startConsuming() {
        registry.getListenerContainers().forEach(container -> {
            if (!container.isRunning()) {
                container.start();
            }
        });
    }

    public void stopConsuming() {
        registry.getListenerContainers().forEach(container -> {
            if (container.isRunning()) {
                container.stop();
            }
        });
    }
}

最佳實踐與注意事項

  1. 啟動順序控制
// 使用 @Order 控制多個 Runner 的執(zhí)行順序
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class FirstRunner implements ApplicationRunner {
    // ...
}

@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class LastRunner implements ApplicationRunner {
    // ...
}
  1. 錯誤處理與重試機制
@Override
public void run(ApplicationArguments args) {
    try {
        mqConsumerService.startConsuming();
    } catch (Exception e) {
        // 添加重試邏輯
        int maxRetries = 5;
        for (int i = 0; i < maxRetries; i++) {
            try {
                Thread.sleep(5000); // 等待5秒重試
                mqConsumerService.startConsuming();
                break;
            } catch (Exception ex) {
                logger.error("Retry {} failed: {}", i+1, ex.getMessage());
            }
        }
    }
}
  1. 優(yōu)雅關閉
import javax.annotation.PreDestroy;

@Component
public class MqConsumerLifecycle {

    @PreDestroy
    public void onShutdown() {
        // 應用關閉時停止消費
        mqConsumerService.stopConsuming();
    }
}

常見問題解決方案

  1. 依賴未初始化問題
// 使用 @DependsOn 確保依賴順序
@Component
@DependsOn("mqConnectionFactory")
public class MqConsumerStarter implements ApplicationRunner {
    // ...
}
  1. 配置加載問題
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReady() {
    // 確保所有配置已加載
}
  1. 多環(huán)境控制
@Profile("!test") // 不在測試環(huán)境啟用
@Component
public class ProductionMqConsumer implements ApplicationRunner {
    // ...
}
  1. 并發(fā)啟動問題
@Bean
public TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(1);
    executor.setMaxPoolSize(1);
    executor.setWaitForTasksToCompleteOnShutdown(true);
    return executor;
}

@Async("taskExecutor")
@Override
public void run(ApplicationArguments args) {
    // 單線程順序執(zhí)行
}

總結

在 Spring Boot 中實現(xiàn)啟動時自動執(zhí)行任務的最佳實踐:

1.?? 推薦使用??:

  • ApplicationRunner或 CommandLineRunner:簡單直接
  • @EventListener(ApplicationReadyEvent.class):確保完全就緒

2.?? 復雜場景??:

  • SmartLifecycle:需要生命周期管理
  • @PostConstruct+ @Async:異步執(zhí)行

3.?? 關鍵注意事項??:

  • 確保依賴已初始化
  • 添加錯誤處理和重試機制
  • 實現(xiàn)優(yōu)雅關閉
  • 集成健康檢查
  • 多環(huán)境配置控制

4.?? MQ 消費最佳實踐??:

  • 使用 Spring 原生支持(如 @RabbitListener)
  • 配置連接池和重試機制
  • 監(jiān)控消費狀態(tài)和性能

通過以上方法,可以可靠的在 Spring Boot 應用啟動時自動執(zhí)行 MQ 消費等初始化任務,確保系統(tǒng)穩(wěn)定運行。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

最新評論