第一节 ApplicationRunner 接口的使用

亮子 2025-05-19 16:49:47 426 0 0 0

ApplicationRunner 使用示例

ApplicationRunner 是 Spring Boot 提供的一个接口,用于在 Spring Boot 应用启动后执行一些特定的代码。下面我将通过几个示例演示如何使用它。

基本用法

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@Component
class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("Application started with following arguments:");
        
        // 获取非选项参数
        System.out.println("Non-option arguments: " + args.getNonOptionArgs());
        
        // 获取选项参数
        System.out.println("Option arguments: ");
        args.getOptionNames().forEach(name -> {
            System.out.println(name + "=" + args.getOptionValues(name));
        });
        
        // 检查是否包含某个选项
        if (args.containsOption("debug")) {
            System.out.println("Debug mode is enabled");
        }
    }
}

多个 ApplicationRunner 的执行顺序

可以通过 @Order 注解来控制多个 ApplicationRunner 的执行顺序:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
class FirstRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("This runs first (order=1)");
    }
}

@Component
@Order(2)
class SecondRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("This runs second (order=2)");
    }
}

实际应用场景示例

1. 启动时加载缓存

@Component
public class CacheLoader implements ApplicationRunner {
    private final SomeCacheService cacheService;
    
    public CacheLoader(SomeCacheService cacheService) {
        this.cacheService = cacheService;
    }
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("Loading data into cache...");
        cacheService.loadDataIntoCache();
        System.out.println("Cache loading completed");
    }
}

2. 启动时检查数据库连接

@Component
public class DbHealthChecker implements ApplicationRunner {
    private final DataSource dataSource;
    
    public DbHealthChecker(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        try (Connection conn = dataSource.getConnection()) {
            System.out.println("Database connection test successful");
        } catch (Exception e) {
            System.err.println("Failed to connect to database: " + e.getMessage());
            throw e;
        }
    }
}

3. 启动时发送通知

@Component
public class StartupNotifier implements ApplicationRunner {
    private final NotificationService notificationService;
    
    public StartupNotifier(NotificationService notificationService) {
        this.notificationService = notificationService;
    }
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        notificationService.send("Application started successfully");
    }
}

与 CommandLineRunner 的区别

ApplicationRunnerCommandLineRunner 功能类似,主要区别在于参数处理方式:

import org.springframework.boot.CommandLineRunner;

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner receives raw args:");
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

ApplicationRunner 提供了更结构化的参数访问方式,而 CommandLineRunner 提供原始的参数数组。

最佳实践

  1. 将启动任务分解为多个小的、专注的 ApplicationRunner 实现
  2. 使用 @Order 控制关键任务的执行顺序
  3. 考虑添加适当的日志记录和错误处理
  4. 对于长时间运行的任务,考虑使用异步执行

希望这些示例能帮助你理解和使用 ApplicationRunner。在实际项目中,它非常适合执行那些需要在应用完全启动后运行的一次性初始化任务。