CommandLineRunner 是什么?

在 Spring Boot 里,CommandLineRunner 是一个非常常用、但又容易被低估的启动钩子接口。


一、CommandLineRunner 是什么?

CommandLineRunner 是 Spring Boot 提供的一个接口:

java 复制代码
public interface CommandLineRunner {
    void run(String... args) throws Exception;
}

👉 只做一件事:

在 Spring Boot 应用启动完成后,执行一段代码


二、什么时候执行?(生命周期位置)

Spring Boot 启动顺序(简化版):

复制代码
1. SpringApplication.run()
2. 创建 ApplicationContext
3. 扫描 Bean / 注入依赖
4. 执行 @PostConstruct
5. 执行 CommandLineRunner / ApplicationRunner
6. 启动完成(应用对外可用)

📌 关键点:

  • 所有 Bean 已经初始化完成
  • @Autowired 可以正常用
  • 适合做 启动后初始化逻辑

三、最基本用法

方式一:实现接口(最常见)

java 复制代码
@Component
public class InitRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Spring Boot 启动完成");
    }
}

启动后控制台输出:

复制代码
Spring Boot 启动完成

方式二:@Bean 方式(更灵活)

java 复制代码
@Bean
public CommandLineRunner init() {
    return args -> {
        System.out.println("执行初始化逻辑");
    };
}

适合 配置类中集中管理启动逻辑。


四、args 是什么?

args 就是 启动 JVM 时的命令行参数

bash 复制代码
java -jar app.jar --env=prod --debug=true

在 run 里:

java 复制代码
@Override
public void run(String... args) {
    for (String arg : args) {
        System.out.println(arg);
    }
}

输出:

复制代码
--env=prod
--debug=true

📌 注意:

  • Spring 的 application.properties 参数也会被解析,但这里拿到的是原始命令行

五、多个 CommandLineRunner 的执行顺序

如果你有多个 Runner:

java 复制代码
@Component
@Order(1)
public class FirstRunner implements CommandLineRunner {
    public void run(String... args) {
        System.out.println("First");
    }
}
java 复制代码
@Component
@Order(2)
public class SecondRunner implements CommandLineRunner {
    public void run(String... args) {
        System.out.println("Second");
    }
}

执行顺序:

复制代码
First
Second

📌 规则:

  • 数字 越小越先执行
  • 也可以实现 Ordered 接口

六、和 ApplicationRunner 的区别(面试常问)

对比项 CommandLineRunner ApplicationRunner
参数 String... args ApplicationArguments
参数解析 需要自己拆 已解析(key-value)
易用性 简单 更强
使用频率 ⭐⭐⭐⭐⭐ ⭐⭐⭐

ApplicationRunner 示例:

java 复制代码
@Component
public class AppRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        args.getOptionNames().forEach(System.out::println);
    }
}

七、常见使用场景(非常重要)

1️⃣ 初始化缓存(Redis / 本地缓存)

java 复制代码
@Component
public class CacheInitRunner implements CommandLineRunner {

    @Autowired
    private UserService userService;

    @Override
    public void run(String... args) {
        userService.loadAllUsersToCache();
    }
}

✔ 广告 / 游戏后台非常常见

✔ 你之前提到 Redis、广告初始化,这个用法很典型


2️⃣ 启动时校验配置

java 复制代码
@Override
public void run(String... args) {
    if (StringUtils.isEmpty(apiKey)) {
        throw new RuntimeException("API_KEY 未配置");
    }
}

📌 失败就让服务启动失败


3️⃣ 初始化定时任务 / 监听器

java 复制代码
@Override
public void run(String... args) {
    taskManager.start();
}

4️⃣ 数据迁移 / 表结构检查(轻量级)

java 复制代码
@Override
public void run(String... args) {
    migrateService.checkAndFix();
}

5️⃣ 游戏 / 广告 SDK 初始化

你做广告变现,这种非常常见:

java 复制代码
@Override
public void run(String... args) {
    AdConfig.init();
    SdkManager.load();
}

八、和 @PostConstruct 的区别(重点)

对比 @PostConstruct CommandLineRunner
执行时机 单个 Bean 初始化后 全部 Bean 初始化完成
是否能注入其他 Bean 有风险 安全
执行次数 每个 Bean 一次 全局一次
适合做 Bean 内部初始化 系统级初始化

📌 经验法则:

  • Bean 自己的事 → @PostConstruct
  • 系统启动的事 → CommandLineRunner

九、注意事项(踩坑点)

❌ 1. 不要写阻塞死循环

java 复制代码
@Override
public void run(String... args) {
    while (true) {} // ❌ 服务卡死
}

✔ 如果要长任务,新开线程


❌ 2. 不要写超慢逻辑

  • 会 拖慢服务启动
  • Kubernetes / 云环境容易被判定启动失败

✔ 推荐做法

java 复制代码
@Override
public void run(String... args) {
    CompletableFuture.runAsync(() -> initHeavyTask());
}

十、一句话总结

CommandLineRunner 是 Spring Boot 提供的启动完成回调接口,用于在容器完全初始化后执行系统级初始化逻辑,常用于缓存预热、配置校验、任务启动等场景。

相关推荐
2301_780789666 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
学长毕设7 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn8 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川8 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵8 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David8 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1009 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin9 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质10 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain37610 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis