【推荐】Spring Boot 程序初始化实战: CommandLineRunner 和 ApplicationRunner

Spring Boot 启动后置任务:ApplicationRunner 实战与进阶 本文深入探讨了Spring Boot中ApplicationRunner的实战应用与进阶技巧,包括核心用法、执行顺序控制、高级应用场景及性能优化建议。通过实际案例展示了如何利用ApplicationRunner进行缓存预热、命令行参数解析等操作,显著提升应用启动效率。 阅读详情

我们在开发过程中会有这样的场景:需要在容器启动的时候执行一些内容,比如:读取配置文件信息,数据库连接,删除临时文件,清除缓存信息。在Spring Boot中给我们提供了两个接口来帮助我们实现这样的需求。这两个接口就是我们今天要讲的

  1. CommandLineRunner
  2. ApplicationRunner,

他们的执行时机为容器启动完成的时候。使用起来非常简单。只需要实现CommandLineRunner或者ApplicationRunner接口。

如果是Spring 环境下,则可以参看本博的下面的文章讲如何在Spring环境做初始化操作的。

https://blog.youkuaiyun.com/bigtree_3721/article/details/103735767。

如果在SpringBoot应用启动的时候需要执行特定的动作,可以利用CommandLineRunner或者ApplicationRunner。实现了CommandLineRunner或者ApplicationRunner接口的Component会在 所有Spring Beans都初始化之后,SpringApplication.run()之前执行,非常适合在应用程序启动之初进行一些数据初始化的工作。

共同点:

其一 执行时机都是在容器启动完成的时候进行执行;其二 这两个接口中都有一个run()方法;

如果程序里既有ApplicationRunner ,也有CommandLineRunner代码 ,

则ApplicationRunner 先运行,而CommandLineRunner 后运行。

不同点:

ApplicationRunner中run方法的参数为ApplicationArguments,

而CommandLineRunner接口中run方法的参数为String数组。

问题提出: 如果有多个实现类,而我们需要按照一定的顺序执行的话,那么应该怎么办呢?

解决方案:

方法1)可以在实现类上加上@Order注解指定执行的顺序;

方法2)可以在实现类上实现Ordered接口来标识。

需要注意:数字越小,优先级越高,也就是@Order(1)注解的类会在@Order(2)注解的类之前执行。

 

下面展示了如何在程序中使用CommandLineRunner和ApplicationRunner。

Maven配置

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.concretepage</groupId>
    <artifactId>spring-boot-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>spring-demo</name>
    <description>Spring Boot Demo Project</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies> 
    <build>
        <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        </plugins>
    </build>
</project> 

CommandLineRunner

CommandLineRunner是个接口,有一个run()方法。为了使用CommandLineRunner我们需要创建一个类实现该接口并覆盖run()方法。使用@Component注解实现类。当SpringApplication.run()启动spring boot程序时,启动完成之前,CommandLineRunner.run()会被执行。CommandLineRunner的run()方法接收启动服务时传过来的参数。

run(String... args)

参数为String数组。

CommandLineRunnerBean.java

package com.concretepage.bean;

import java.util.Arrays;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class CommandLineRunnerBean implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CommandLineRunnerBean.class);  
    public void run(String... args) {
        String strArgs = Arrays.stream(args).collect(Collectors.joining("|"));
        logger.info("Application started with arguments:" + strArgs);
    }
} 

MyApplication.java

package com.concretepage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.concretepage.service.HelloService;

@SpringBootApplication
public class MyApplication {
    private static final Logger logger = LoggerFactory.getLogger(MyApplication.class);
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args);
        HelloService service =  context.getBean(HelloService.class);
        logger.info(service.getMessage());
        }       
} 

我们也可以创建一个service。一旦Spring boot启动完成service就会执行。

这意味着SpringApplication.run()执行完成后service的方法就会执行。
HelloService.java

package com.concretepage.service;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    public String getMessage(){
        return "Hello World!";
    }
}

现在使用带有参数的可执行jar运行程序。spring-boot-demo-0.0.1-SNAPSHOT.jar为生成的jar文件。执行命令如下:

java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar data1 data2 data3 

输出结果为:

2017-03-19 13:38:38.909  INFO 1036 --- [main] c.c.bean.CommandLineRunnerBean  : Application started with arguments:data1|data2|data3
2017-03-19 13:38:38.914  INFO 1036 --- [main] com.concretepage.MyApplication  : Started MyApplication in 1.398 seconds (JVM running for 1.82)
2017-03-19 13:38:38.915  INFO 1036 --- [main] com.concretepage.MyApplication  : Hello World! 

ApplicationRunner

ApplicationRunner和CommandLineRunner的作用相同。在SpringApplication.run()完成spring boot启动之前,ApplicationRunner的run()方法会被执行。

run(ApplicationArguments args) 

可以看到,CommandLineRunner.run()接收String数组作为参数,而ApplicationRunner.run()接收ApplicationArguments作为参数。这些参数是启动spring boot程序时传给main()方法的。

ApplicationRunnerBean.java

package com.concretepage.bean;

import java.util.Arrays;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class ApplicationRunnerBean implements ApplicationRunner {
    private static final Logger logger = LoggerFactory.getLogger(ApplicationRunnerBean.class);  
    @Override
    public void run(ApplicationArguments arg0) throws Exception {
            String strArgs = Arrays.stream(arg0.getSourceArgs()).collect(Collectors.joining("|"));
            logger.info("Application started with arguments:" + strArgs);
    }
} 

创建可执行jar包并使用如下参数运行:

java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar data1 data2 data3 

输出结果为:

2017-03-19 16:26:06.952  INFO 5004 --- [           main] c.c.bean.ApplicationRunnerBean           : Application started with arguments:data1|data2|data3
2017-03-19 16:26:06.956  INFO 5004 --- [           main] com.concretepage.MyApplication           : Started MyApplication in 1.334 seconds (JVM running for 1.797)
2017-03-19 16:26:06.957  INFO 5004 --- [           main] com.concretepage.MyApplication           : Hello World! 

CommandLineRunner和ApplicationRunner的执行顺序

在spring boot程序中,我们可以使用不止一个实现CommandLineRunner和ApplicationRunner的bean。为了有序执行这些bean的run()方法,可以使用@Order注解或Ordered接口。例子中我们创建了两个实现CommandLineRunner接口的bean和两个实现ApplicationRunner接口的bean。我们使用@Order注解按顺序执行这四个bean。

CommandLineRunnerBean1.java

@Component
@Order(1)
public class CommandLineRunnerBean1 implements CommandLineRunner {
    public void run(String... args) {
        System.out.println("CommandLineRunnerBean 1");
    }
}

ApplicationRunnerBean1.java

@Component
@Order(2)
public class ApplicationRunnerBean1 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments arg0) throws Exception {
        System.out.println("ApplicationRunnerBean 1");
    }
}

CommandLineRunnerBean2.java

@Component
@Order(3)
public class CommandLineRunnerBean2 implements CommandLineRunner {
    public void run(String... args) {
        System.out.println("CommandLineRunnerBean 2");
    }
}

ApplicationRunnerBean2.java

@Component
@Order(4)
public class ApplicationRunnerBean2 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments arg0) throws Exception {
        System.out.println("ApplicationRunnerBean 2");
    }
} 

输出结果为:

CommandLineRunnerBean 1
ApplicationRunnerBean 1
CommandLineRunnerBean 2
ApplicationRunnerBean 2 

 

 

Spring Boot 框架整体启动流程详解 作者其他文章:Spring Boot 3.x系列文章Spring Boot 2.7.8 中文参考指南(一)Spring Boot 2.7.8 中文参考指南(二)-WebSpring Boot 源码阅读初始化环境搭建Spring Boot 框架整体启动流程详解Prometheus 系列文章Prometheus 的介绍和安装直观感受PromQL及其数据类型PromQL之选择器和运算符PromQL之函数Prometheus 告警机制介绍及命令解读Prometheus 告警模块配置深度解析。 阅读详情

相关推荐

Django Cookie/Session

Cookie是一种小型的文本文件,通常由Web服务器发送到用户浏览器,并存储在用户的本地计算机上。当用户再次访问该网站时,浏览器会将Cookie发送回服务器,从而实现用户身份验证、个性化设置等功能。Session是一种在服务器端存储用户会话信息的方式。与Cookie不同,Session数据存储在服务器上,而不是客户端。Django框架通过在客户端存储一个Session ID来实现Session的跟踪。Django框架的Cookie/Session机制为开发者提供了方便的数据存储和会话管理功能。

froginwe11的博客 467

深入理解 Spring Boot 的 CommandLineRunner 原理及使用

run方法:该方法在应用程序启动后被调用。:命令行参数数组。:允许抛出任何异常。是 Spring Boot 提供的一个非常有用的接口,可以帮助你在应用程序启动后执行初始化任务。通过实现run方法,你可以轻松地执行各种初始化操作,并且可以通过命令行参数传递必要的配置信息。本文通过多个示例详细介绍了如何在实际项目中使用,希望对你有所帮助。

weixin_43841461的博客 4398

STM32驱动数码管:从硬件连接到动态显示实现

本文详细介绍了使用STM32单片机驱动数码管的完整流程,从硬件连接到软件实现。内容涵盖共阳/共阴数码管原理、GPIO配置、段码表生成,并重点解析了多位数码管动态显示的核心技术,包括动态扫描原理、消影处理及实战代码,帮助开发者快速掌握这一嵌入式开发基础技能。

p5l2m9n4o6q的博客 575

CommandLineRunner接口介绍

文章目录CommandLineRunner接口介绍1. CommandLineRunner接口使用2. ApplicationRunner与CommandLineRunner3. ApplicationArguments 源码分析 CommandLineRunner接口介绍   CommandLineRunner接口是在容器启动成功后的最后一步回调(类似开机自启动)。 1. CommandLine...

Chavaer 5508

【隐私计算】从本地加法到在线乘法:Beaver Triple如何重塑算术秘密分享的运算效率

本文深入探讨了Beaver Triple在算术秘密分享中的关键作用,显著提升了隐私计算中的乘法运算效率。通过对比加法与乘法的实现差异,详细解析了Beaver Triple的预处理机制和在线计算优化,展示了其在减少通信量和计算时间方面的革命性突破。

weixin_29227585的博客 436

从零开始学习信号完整性(SIPI)--1 简介

信号完整性就是研究如何让驱动芯片发出的信号经过传输通道被接收芯片正确接收的学问。 信号完整性包含了三个要素: 信号:是被传输的主体,我们首先要了解、熟悉信号的特性。 芯片:分为驱动芯片和接收芯片,信号完整性工程师就是要实现信号在驱动芯片和接收芯片之间的正确传输。 传输通道:是传输信号的介质,是信号所走的“路”。如何实现信号的正确传输呢?那就要信号完整性工程师为信号“修路”、“搭桥”。

qq_29476769的博客 4万+

Spring boot CommandLineRunner接口使用例子

前言 Spring boot的CommandLineRunner接口主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次。 如何使用CommandLineRunner接口 我们可以用以下三种方式去使用CommandLineRunner接口: 1)和@Component注解一起使用 这种使用方式相当简便,如下所示: @Component public cl...

weixin_34380296的博客 258

在MacBook M1/M2上,手把手教你打包包含嵌入模型的RagFlow Docker镜像(避坑指南)

本文详细指导如何在MacBook M1/M2上构建ARM64架构的RagFlow Docker镜像,涵盖环境准备、依赖处理、镜像构建及性能优化全流程。特别针对Apple Silicon芯片的兼容性问题提供解决方案,帮助开发者高效完成本地开发环境搭建。

weixin_26908317的博客 242

CommandLineRunner接口中run方法的执行时机

CommandLineRunner接口中run(): @FunctionalInterface public interface CommandLineRunner { void run(String... args) throws Exception; } 使用时我们需要实现接口并实现run()方法 @SpringBootApplication public class Application implements CommandLineRunner { @Resource priv..

Jywudiok的博客 1976

音频测试专题

麦克风与扬声器单体测试指标及整机性能测试概述 麦克风测试指标包括频率响应、灵敏度、指向性等10项关键参数,用于评估声音捕捉和信号转换性能。扬声器测试包含频率响应、灵敏度等12项指标,涉及声学特性和物理参数。整机性能测试覆盖安静、嘈杂和正常三种环境,重点检测麦克风底噪、清晰度、扬声器音量及通话质量等12项功能指标。两类单体测试与整机测试共同构成完整的音频设备质量评估体系,确保产品在不同场景下的性能表现。

weixin_52640906的博客 1317

告别玄学调试:手把手教你读懂全志芯片的sys_config.fex配置文件(以i2c配置为例)

本文深入解析全志芯片的sys_config.fex配置文件,以I2C设备驱动为例,详细讲解从引脚定义到驱动加载的全过程。通过实战案例和高级调试技巧,帮助开发者快速掌握硬件配置与内核驱动的联动机制,提升开发效率。

weixin_33737134的博客 418

java 执行commandline,CommandLineRunner是一个带有run方法的简单spring引导接口。Spring Boot启动后将自动调用实现CommandLineRunner接...

CommandLineRunner是一个带有run方法的简单spring引导接口。Spring Boot启动后将自动调用实现CommandLineRunner接口的所有bean的run方法。Command Line Runner在加载应用程序上下文之后以及Spring Application run方法完成之前执行,相当于你的应用的初始化过程,一般用来实现一些数据预先加载或预先处理。@Spring...

weixin_35990358的博客 1144

【时空图神经网络 & 交通】相关模型3:STFGNN | 空间-时间依赖性 | 基于数据驱动的方法来生成“时间图” | 时空融合图模块,门控卷积模块 | 动态时间规整 | 顶会文章解析

STFGNN(时空融合图神经网络)在交通流量预测中的优势主要体现在以下几个方面:首先,它提出了一种数据驱动的方法生成“时间图”,弥补了传统空间图可能无法反映的某些相关性。其次,STFGNN通过并行处理不同时间段的空间图和时间图,有效地学习隐藏的时空依赖关系。此外,它将融合图模块与门控卷积模块整合到一个统一层中,通过层层堆叠处理长序列,进一步增强了模型的表达能力。实验结果表明,STFGNN在多个交通数据集上表现出色,优于其他基准方法,展示了其在实际应用中的强大潜力。

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 384

Spring Boot 启动后执行器深度指南:CommandLineRunner vs ApplicationRunner

Spring Boot 启动后任务执行指南:CommandLineRunner vs ApplicationRunner 核心摘要 Spring Boot 提供了两种在应用启动后执行初始化任务的接口: CommandLineRunner 接收原始字符串数组参数(String[] args) 适用于简单参数处理场景 执行时机:应用上下文刷新后,服务就绪前 ApplicationRunner(推荐) 封装参数为ApplicationArguments对象,支持选项/非选项参数解析 提供更强大的参数处理能力(如-

python15397的博客 820

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Springboot 初始化操作

在使用Springboot过程中,或多或少我们会遇到在Springboot启动时要初始化类,或者加载文件之类的一些操作

做一个有思想的技术人 1316

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SpringBoot31-ApplicationRunner 详细讲解

特性说明用途应用启动完成后执行初始化逻辑优势保证所有 Bean 初始化完成,支持依赖注入,可访问命令行参数注意事项如果抛出异常,应用启动会失败;可用 @Order 控制多个 Runner 的执行顺序替代方案。

qq_31532983的博客 921

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Spring Boot启动后,除了ApplicationRunner,你还可以用这几种方式执行初始化任务

本文深入探讨了Spring Boot启动后执行初始化任务的五种方案,包括@PostConstruct、SmartInitializingSingleton、CommandLineRunner、ApplicationRunner和@EventListener(ReadyEvent),并对比了它们的触发时机、参数获取能力和异常处理影响。通过场景化选型指南和高级控制技巧,帮助开发者在数据预热、连接池初始化等关键场景中做出精准选择,提升应用启动效率和稳定性。

weixin_33742618的博客 464

Spring Boot应用启动后初始化:四种方案对比与生产实践指南

在Java企业级应用开发中,应用启动后的初始化逻辑是确保系统稳定运行的关键环节。其核心原理在于利用框架提供的生命周期钩子,在特定阶段执行预设任务,从而完成资源准备和数据预热。这一机制的技术价值在于提升应用启动后的即时响应能力,避免首次请求的冷启动延迟,保障服务的高可用性。典型的应用场景包括缓存预热、数据库连接池初始化、配置中心数据拉取以及向注册中心上报服务实例。本文聚焦于Spring Boot框架,深入剖析其提供的@PostConstruct、CommandLineRunner、ApplicationRun

weixin_30608503的博客 410

Spring Boot应用启动自激活:缓存预热与资源初始化实践指南

在软件工程中,应用启动初始化是确保系统就绪的关键环节,其核心原理在于利用容器生命周期管理机制,在组件装配完成后自动执行预设逻辑。这一技术价值在于提升系统自治能力,避免手动调用的繁琐与遗漏,从而增强代码健壮性和可维护性。其典型应用场景包括微服务启动时的缓存预热、数据库连接池建立、外部客户端初始化以及配置加载等。本文聚焦于Spring框架下的实现,深入探讨了如何通过@PostConstruct、ApplicationRunner及事件监听等机制,结合异步执行与线程模型,构建高效可靠的自激活组件,并特别针对缓存预

weixin_30555515的博客 400

Spring Boot CommandLineRunner 详解与应用实践

CommandLineRunner 是 Spring Boot 框架中用于在应用启动后执行特定任务的关键接口,属于 Spring 应用生命周期的重要扩展点。其核心原理是通过实现 run 方法,在应用上下文初始化完成但未正式提供服务前执行自定义逻辑。这种机制为开发者提供了标准化的启动任务处理方案,在数据预加载、连接测试、环境校验等场景具有重要技术价值。通过 @Order 注解或 Ordered 接口可以精确控制多个 Runner 的执行顺序,而结合条件化执行(@Conditional)和异常处理机制则能构建更

cqwmy840702的博客 514

Spring Boot应用启动后初始化:精准时机选择与最佳实践

在Java企业级应用开发中,应用启动后的初始化是确保系统稳定运行的关键环节。其核心原理在于理解Spring框架的生命周期事件机制,通过监听特定事件在正确的时机执行代码。这一技术的价值在于避免因初始化时机不当导致的空指针异常、循环依赖等问题,从而提升应用的健壮性和启动成功率。常见的应用场景包括缓存预热、配置加载、数据库连接池初始化以及向注册中心上报服务等。本文聚焦于Spring Boot项目启动后初始化的核心需求,深入对比了@PostConstruct、ApplicationRunner与监听Applicat

weixin_30216561的博客 337

【Spring】CommandLineRunner接口

本文深入讲解 Spring Boot 的 CommandLineRunner 接口:从源码、基础使用、执行顺序到缓存预热、数据库初始化等实战场景,以及常见踩坑与最佳实践,帮你彻底掌握启动回调机制。

406

使用CommandLineRunner应该注意什么

场景最佳实践​依赖管理​使用构造器注入,避免循环依赖​异常处理​捕获所有异常,关键失败终止应用​耗时操作​使用异步执行,不阻塞主线程​资源清理​监听 ContextClosedEvent 释放资源​环境区分​使用 @Profile 控制环境特定逻辑​执行顺序​使用 @Order 明确初始化顺序​幂等设计​确保多次执行不会产生副作用​参数访问​使用 ApplicationArguments 解析复杂参数​测试策略​直接调用 run() 方法进行单元测试。

zwh1zwh的博客 788

Spring Boot启动依赖管理:利用Actuator与ApplicationRunner实现优雅健康检查

在微服务架构中,服务间的启动依赖管理是保障系统稳定性的关键。其核心原理在于通过延迟检查机制,将外部依赖验证从Spring容器初始化阶段剥离,避免因依赖服务未就绪导致应用启动失败。这一技术方案的价值在于提升系统健壮性和部署成功率,尤其适用于数据库、配置中心、下游服务等强依赖场景。通过结合Spring Boot Actuator的健康检查机制和自定义ApplicationRunner,开发者可以实现对外部服务的启动验证与延迟等待,有效解决微服务架构中常见的启动依赖问题。

weixin_33727510的博客 354

详解Spring Boot 启动时执行特定代码逻辑实现方案

书接上回,我们总结了,大致分为环境配置、IOC容器bean加载、事件通知等,具体详细总结可自行调转查看。今天我们来看看一个平时在业务开发中常见的逻辑场景。在开发 Spring Boot 应用时,我们经常需要在项目启动时执行一些初始化逻辑,比如加载缓存、连接外部系统、初始化配置信息等。Spring Boot 提供了多种实现方式,允许我们在应用启动的不同阶段插入代码逻辑。本文将结合启动过程详细介绍这些方式,并说明适用的场景及实现示例。

weixin_41821642的博客 1088
上一篇: 【推荐】mysql联合 索引(复合索引)的探讨
下一篇: springmvc在启动工程的时候就访问数据库,加载一些共同的数据
大树叶
博客等级 码龄12年 1171粉丝 664原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值