小工具知识网

当前位置: 首页 > 行业知识 > SpringBoot中CommandLineRunner详解(含源码)

行业知识

SpringBoot中CommandLineRunner详解(含源码)

2026-11-01 15:52:57 来源:互联网转载

文章目录

      • 前言
      • 实例
        • 导入库
        • application.yaml
        • Runner
        • SpringBootCommandLineRunnerApplication
        • 执行结果
        • 先后顺序示例
          • OrderRunner1
          • OrderRunner2
          • 执行结果
          • 通常用法
            • 加载初始化数据
              • 示例
              • 启动后打印应用信息
                • 示例
                • 启动异步任务
                  • 示例
                  • 接口健康检查
                    • 示例
                    • 外部服务调用
                      • 示例
                      • 参数校验
                        • 示例
                        • 动态设置配置
                          • 示例
                            • application.yaml
                            • MyConfig
                            • ConfigRunner
                            • 启动阻塞
                            • 总结
                            • 源码获取
                            • 写在最后

                              前言

                              Spring Boot的CommandLineRunner接口是一个函数式接口,用于在Spring Boot应用程序启动后执行一些初始化操作。它提供了一个run方法,该方法在应用程序启动后被调用。

                              使用CommandLineRunner接口,可以在应用程序启动后执行一些必要的初始化操作,例如加载配置文件、初始化数据库连接、创建默认数据等。可以通过实现CommandLineRunner接口,并重写run方法来定义自己的初始化逻辑。


                              实例

                              导入库
                                  org.springframework.boot    spring-boot-starter-parent    3.1.0org.examplespringboot-CommandLineRunner1.0-SNAPSHOTSpring Boot bannerSpring Boot and commandLineRunner    17    17    UTF-8            org.springframework.boot        spring-boot-starter-web                org.projectlombok        lombok    
                              application.yaml
                              server:  port: 8080spring:  profiles:    active: dev
                              Runner
                              import lombok.extern.slf4j.Slf4j;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;@Component@Slf4jpublic class Runner implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        log.info("The Runner start to initialize ...");    }}
                              SpringBootCommandLineRunnerApplication
                              import lombok.extern.slf4j.Slf4j;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication@Slf4jpublic class SpringBootCommandLineRunnerApplication {    public static void main(String[] args) {        SpringApplication.run(SpringBootCommandLineRunnerApplication.class, args);        log.info("The service to end");    }}
                              执行结果

                              在上面的示例中,我们创建了一个名为MyCommandLineRunner的类,并实现了CommandLineRunner接口。在run方法中,我们可以编写需要在应用程序启动后执行的初始化逻辑。

                              需要注意的是,实现CommandLineRunner接口的类需要被Spring容器扫描到,可以使用@Component注解或其他方式将其注册为Spring Bean。

                              先后顺序示例

                              可以通过@Order()来设置Runner的先后顺序,在上面例子的基础上增加

                              OrderRunner1
                              import lombok.extern.slf4j.Slf4j;import org.springframework.boot.CommandLineRunner;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;@Component@Order(1)@Slf4jpublic class OrderRunner1 implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        log.info("The OrderRunner1 start to initialize ...");    }}
                              OrderRunner2
                              import lombok.extern.slf4j.Slf4j;import org.springframework.boot.CommandLineRunner;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;@Component@Order(2)@Slf4jpublic class OrderRunner2 implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        log.info("The OrderRunner2 start to initialize ...");    }}
                              执行结果

                              通常用法

                              加载初始化数据

                              可以实现CommandLineRunner接口,在run方法中加载一些初始化数据到数据库等。适合做一些数据预加载工作。

                              示例
                              @Componentpublic class DataInitializer implements CommandLineRunner {    @Autowired    private UserRepository userRepository;    @Override    public void run(String... args) throws Exception {                // 创建初始用户        User admin = new User("admin", "123456");        userRepository.save(admin);        User normalUser = new User("user", "123456");        userRepository.save(normalUser);                System.out.println("数据加载完毕!");    }}

                              这里创建了一个 DataInitializer 类,实现 CommandLineRunner 接口。在 run() 方法中,我们注入了 UserRepository,然后创建了两个用户对象保存到数据库中。这个类会在 Spring Boot 应用启动完成后执行,从而实现了数据预加载的效果。通过 CommandLineRunner,我们可以灵活地在 Spring Boot 启动时进行一些初始化操作,如预先加载测试数据、插入管理员账户等,很好地增强了应用的功能。

                              假设我们有一个User模型和用户Repository,需要在Spring Boot启动时预加载几个用户数据,可以这样使用CommandLineRunner:

                              @Componentpublic class DataInitializer implements CommandLineRunner {    @Autowired    private UserRepository userRepository;    @Override    public void run(String... args) throws Exception {                // 清除所有数据        userRepository.deleteAll();                 // 创建几个用户        User user1 = new User("John", "john@example.com");        User user2 = new User("Mary", "mary@example.com");                userRepository.save(user1);        userRepository.save(user2);                // 打印已保存用户数        System.out.println("Number of users saved: " + userRepository.count());    }}

                              这里我们实现了CommandLineRunner接口,然后注入UserRepository bean。在run方法中,首先清空所有数据,然后创建两个用户对象并保存,最后打印已保存的用户数。这样在Spring Boot应用启动完成后,就会自动执行run方法,预加载指定的用户数据。

                              启动后打印应用信息

                              可以打印出一些应用启动信息,如启动端口、运行环境信息等,用于确认应用配置。

                              示例
                              @Component@Slf4jpublic class AppInfoPrinter implements CommandLineRunner {    @Autowired    private Environment environment;    @Override    public void run(String... args) throws Exception {        log.info("========= 打印启动信息 =========");        // 打印应用端口        log.info(("端口号: " + environment.getProperty("server.port")));        // 打印当前环境        log.info("当前环境: " + environment.getProperty("spring.profiles.active"));        // 打印JDK版本        log.info("JDK 版本: " + System.getProperty("java.version"));        log.info("========= 打印启动信息结束 =========");    }}

                              执行打印结果

                              启动异步任务

                              可以使用多线程启动一些异步任务,进行后台数据处理等复杂业务逻辑。

                              示例
                              @Component@Slf4jpublic class AsyncTaskRunner implements CommandLineRunner {    @Autowired    private AsyncTaskService asyncTaskService;    @Override    public void run(String... args) throws Exception {        log.info("========= 执行任务 =========");        // 在新线程中执行任务        new Thread(() -> {            asyncTaskService.doTaskOne();            asyncTaskService.doTaskTwo();            asyncTaskService.doTaskThree();        }).start();    }}@Service@Slf4jclass AsyncTaskService {    public void doTaskOne() {        log.info("执行任务1");    }    public void doTaskTwo() {        log.info("执行任务2");    }    public void doTaskThree() {        log.info("执行任务3");    }}

                              执行结果

                              [           main] org.example.runner.AsyncTaskRunner       : ========= 执行任务 =========[       Thread-1] org.example.runner.AsyncTaskService      : 执行任务1[       Thread-1] org.example.runner.AsyncTaskService      : 执行任务2[       Thread-1] org.example.runner.AsyncTaskService      : 执行任务3
                              接口健康检查

                              可以调用并验证依赖服务的健康状态,如果不正常可以终止Spring Boot启动。

                              示例
                              @Component@Slf4jpublic class HealthCheckRunner implements CommandLineRunner {    @Autowired    private DatabaseService databaseService;    @Autowired    private MessageQueueService messageQueueService;    @Override    public void run(String... args) throws Exception {        if(!databaseService.isConnected()) {            log.error("数据库服务不可用,退出应用!");            System.exit(1);        }        if(!messageQueueService.isConnected()) {            log.error("消息队列服务不可用,退出应用!");            System.exit(1);        }        log.info("所有服务正常,应用启动。");    }}

                              这里我们注入两个依赖服务 DatabaseService 和 MessageQueueService。在run方法中,调用它们的健康检查方法,如果任何一个服务不可用,则直接调用System.exit(1)退出Spring Boot应用启动。

                              外部服务调用

                              可以在启动时调用外部服务,进行验证、数据同步等操作。

                              示例
                              @Componentpublic class OtherServiceCheckRunner implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        // 健康检查的URL        String healthCheckUrl = "http://localhost:8080/actuator/health";        RestTemplate restTemplate = new RestTemplate();        // 发送GET请求进行健康检查        String response = restTemplate.getForObject(healthCheckUrl, String.class);        // 根据响应判断健康状态        if (response.contains("\"status\":\"UP\"")) {            System.out.println("Application is healthy");        } else {            System.out.println("Application is not healthy");        }    }}
                              参数校验

                              可以对输入的运行参数做校验,如果不满足条件可以终止Spring Boot启动。

                              示例
                              @Component@Slf4jpublic class ParameterValidator implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        // 校验参数1        if(args.length  

                              在run方法中,我们可以对main方法输入的参数args进行自定义校验:

                              • 检查参数数量
                              • 校验参数类型

                                如果参数不满足需求,可以直接调用System.exit(1)来终止Spring Boot的启动。这样就可以在应用启动前验证参数的正确性,避免应用启动后发生未知错误。

                                动态设置配置

                                可以根据运行参数等条件动态设置Spring Boot的配置,实现不同环境的适配。

                                示例
                                application.yaml
                                myconfig:  foo: 十五  bar: 1
                                MyConfig
                                @Component@Data@ConfigurationProperties(prefix = "myconfig")public class MyConfig {    private String foo;    private int bar;// getter和setter方法省略    @Override    public String toString() {        return "MyConfig{" +                "foo='" + foo + '\'' +                ", bar=" + bar +                '}';    }}
                                ConfigRunner
                                @Component@EnableConfigurationProperties(MyConfig.class)public class ConfigRunner implements CommandLineRunner {    @Autowired    private MyConfig myConfig;    @Override    public void run(String... args) throws Exception {// 打印当前配置        System.out.println("Current config: " + myConfig);// 动态设置配置        myConfig.setFoo("new value");        myConfig.setBar(100);// 打印更新后的配置        System.out.println("Updated config: " + myConfig);    }}
                                启动阻塞

                                可以使应用启动后阻塞住主线程,防止main方法直接退出,从而保持Spring Boot应用运行。

                                示例

                                @Component@Slf4jpublic class StartBlocker implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        // 加载提示信息        log.info("正在等待管理员授权...");        // 等待授权,阻塞启动流程        waitAuth();        // 授权完成后继续启动        log.info("管理员已授权,应用启动中...");    }    private void waitAuth() {        // ***循环模拟等待管理员操作授权        while(true) {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                break;            }        }    }}

                                总结

                                通过 CommandLineRunner,我们可以深度控制 Spring Boot 应用的启动流程,在应用启动阶段增强各种自定义逻辑。是 Spring Boot 提供的一个很实用的扩展点。


                                源码获取

                                如果需要完整源码请关注公众号"架构殿堂" ,回复 "SpringBoot+CommandLineRunner"即可获得


                                写在最后

                                感谢您的支持和鼓励!

                                如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot, spring cloud等系列文章,一系列干货随时送达!

上一篇:万网怎么配置phpmyadmin?

下一篇:vue3-封装AES(CryptoJS)前端加密解密通信