Skip to content

Runner

在 Spring Boot 中,Runner 是一种用于在应用程序启动完成后执行特定任务的机制。

Spring Boot 提供了两种主要类型的 Runner 接口:CommandLineRunnerApplicationRunner。它们都可以用来定义在应用程序启动后立即执行的代码逻辑,但它们接受不同的参数类型。

1. CommandLineRunner

CommandLineRunner 是一个简单的接口,它包含一个 run(String... args) 方法,该方法会在应用程序上下文完全加载后立即执行。你可以实现这个接口,并通过 @Component 或者 @Bean 将其实例注册到 Spring 容器中。

示例代码

java
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Executing CommandLineRunner after application startup.");
        // 执行初始化任务或业务逻辑
    }
}

特点

  • 接受命令行参数(String... args)。
  • 适用于需要处理命令行参数的任务。
  • 可以有多个 CommandLineRunner 实现类,它们会按照 Ordered 接口或 @Order 注解指定的顺序执行。

2. ApplicationRunner

ApplicationRunner 是另一个类似的接口,但它接受的是 ApplicationArguments 对象作为参数,这使得它可以更方便地访问命令行参数和选项。

示例代码

java
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("Executing ApplicationRunner after application startup.");
        // 执行初始化任务或业务逻辑
        if (args.containsOption("my-option")) {
            System.out.println("Found option: " + args.getOptionValues("my-option"));
        }
        for (String arg : args.getNonOptionArgs()) {
            System.out.println("Non-option argument: " + arg);
        }
    }
}

特点

  • 接受 ApplicationArguments 参数,提供了对命令行参数和选项的更细粒度控制。
  • 同样可以有多个 ApplicationRunner 实现类,它们也会按照 Ordered 接口或 @Order 注解指定的顺序执行。
  • 更推荐使用 ApplicationRunner,因为它提供了更好的 API 来解析命令行参数。

3. 选择 CommandLineRunner 还是 ApplicationRunner

两者的主要区别在于它们如何处理命令行参数:

  • 如果你只需要简单地访问原始的命令行字符串数组,那么 CommandLineRunner 就足够了。
  • 如果你需要更复杂的参数解析(如区分选项参数和非选项参数),则 ApplicationRunner 提供了更好的支持。

4. 执行顺序

当同时存在 CommandLineRunnerApplicationRunner 的实现时,它们的执行顺序由 Ordered 接口或 @Order 注解决定。默认情况下,所有未显式指定顺序的 Runner 实现将按实例化顺序执行。

示例代码

java
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
public class FirstRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("First Runner executing...");
    }
}

@Component
@Order(2)
public class SecondRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("Second Runner executing...");
    }
}

在这个例子中,FirstRunner 会先于 SecondRunner 执行。

Runner 接口为 Spring Boot 应用程序提供了一种简洁的方法来定义启动后的初始化任务或业务逻辑。根据你的需求选择合适的 Runner 类型,并利用 @OrderOrdered 接口来控制执行顺序。无论是简单的命令行参数处理还是更复杂的参数解析,CommandLineRunnerApplicationRunner 都能有效地满足这些需求。