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

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

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

一、應用生命周期回調方式

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ù)庫初始化完成");
    }
}

特點:

  • 在所有ApplicationReadyEvent之前執(zhí)行
  • 可以訪問命令行參數(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("選項參數(shù): " + args.getOptionNames());
        
        // 預熱緩存邏輯
        System.out.println("緩存預熱完成");
    }
}

與CommandLineRunner區(qū)別:

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

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

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

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

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

三、Bean生命周期回調

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)驗證通過");
    }
}

特點:

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

2. InitializingBean 接口

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

與@PostConstruct比較:

  • 功能類似,但屬于Spring接口而非JSR-250標準
  • 執(zhí)行時機稍晚于@PostConstruct

四、Spring Boot特性擴展

1. ApplicationContextInitializer

public class CustomInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 在上下文刷新前執(zhí)行
        System.out.println("應用上下文初始化器執(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("應用開始啟動");
    }
    
    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, 
                                  ConfigurableEnvironment environment) {
        System.out.println("環(huá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ù)");
    }
}

六、初始化方法對比

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

七、最佳實踐建議

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

避免事項:

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

八、高級應用示例

1. 異步初始化

@Component
public class AsyncInitializer {
    
    @EventListener(ApplicationReadyEvent.class)
    @Async
    public void asyncInit() {
        System.out.println("異步初始化開始");
        // 執(zhí)行耗時初始化任務
        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("應用啟動失敗: " + exception.getMessage());
        // 發(fā)送警報或記錄日志
    }
}

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

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("啟動任務執(zhí)行失敗: " + task.getClass().getName(), e);
                }
            });
    }
}

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

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

相關文章

最新評論