• Spring Boot 2.x系列【10】功能篇之使用 ApplicationRunner 、CommandLineRunner


    有道无术,术尚可求,有术无道,止于术。

    本系列Spring Boot版本2.7.0

    概述

    在应用程序启动后,需要执行特定的代码,比如加载缓存数据、打印自定义启动信息等。

    Spring Boot 为我们提供了ApplicationRunnerCommandLineRunner两个接口来实现上面的需求。

    在应用程序启动类SpringApplicationrun方法中,可以看到在最后调用了一个callRunners方法:

    在这里插入图片描述

    callRunners方法中,会在上下文中查询ApplicationRunnerCommandLineRunner类型的Bean 对象,并调用他们的run 方法运行:

    	private void callRunners(ApplicationContext context, ApplicationArguments args) {
    		List<Object> runners = new ArrayList<>();
    		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    		AnnotationAwareOrderComparator.sort(runners);
    		for (Object runner : new LinkedHashSet<>(runners)) {
    			if (runner instanceof ApplicationRunner) {
    				callRunner((ApplicationRunner) runner, args);
    			}
    			if (runner instanceof CommandLineRunner) {
    				callRunner((CommandLineRunner) runner, args);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    由此可见,我们只需要注册ApplicationRunnerCommandLineRunner类型的Bean ,就可以实现在应用启动最后阶段执行特定的代码。

    ApplicationRunner

    ApplicationRunner只定义了一个run方法用于在启动完成后进行方法调用,可以定义多个该类型的Bean ,并且可以通过实现Ordered接口或使用@Order注解进行排序。

    run方法接收一个ApplicationArguments ,也就是应用启动参数,参数具体用法可以参考SpringApplication启动参数使用详解

    @FunctionalInterface
    public interface ApplicationRunner {
    	// 用于运行 bean 的回调
    	void run(ApplicationArguments args) throws Exception;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    案例演示:在应用程序启动完成时,加载字典缓存、打印当前应用的访问地址。

    首先加载缓存,并使用@Order(1)进行排序:

    @Order(1)
    @Component
    public class DictCacheInitializerApplicationRunner implements ApplicationRunner {
    
        @Override
        public void run(ApplicationArguments args) {
            System.out.println("应用启动完成,开始初始化字典缓存....");
            System.out.println("加载中....");
            System.out.println("初始化完成....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    再编写一个打印访问地址的运行器,设置排序为2:

    @Component
    @Order(2)
    public class AddressInitializerApplicationRunner implements ApplicationRunner {
    
        @Value("${server.port}")
        String port;
    
        @Override
        public void run(ApplicationArguments args) {
            System.out.println("应用访问地址:http://localhost:" + port);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    启动程序,可以看到在启动完成后执行了响应的代码,@Order数值越小越先执行:
    在这里插入图片描述

    CommandLineRunner

    CommandLineRunnerApplicationRunner作用用法一样,区别在于他们的参数不同,CommandLineRunner传入的参数是原始的参数集合,比如--name=zhangsan,所以一般很少用到,也就不赘述了。

    @FunctionalInterface
    public interface CommandLineRunner {
    
    	void run(String... args) throws Exception;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    latex中复制到word里面之后如何转变成word自带的公式
    【力扣周赛】第 362 场周赛(⭐差分&匹配&状态压缩DP&矩阵快速幂优化DP&KMP)
    cookie、session、tooken
    【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(8 月 28 日论文合集)
    EPICS记录参考--Histogram记录(histogram)
    Docker知识总结 (二) Docker 底层原理
    论坛介绍|COSCon'23 Web应用开发(W)
    关于Linux系统之VM安装配置(每一个步骤都超级详细的哦!)
    MySQL数据库—创建数据库与数据表
    云架构的一些核心概念
  • 原文地址:https://blog.csdn.net/qq_43437874/article/details/125601382