使用SpringBoot的CommandLineRunner遇到的坑及解决

使用Spring Boot的CommandLineRunner接口可以在应用程序启动时运行一些代码。但是在使用CommandLineRunner时,可能会遇到一些坑,下面是攻略及相应示例:

坑点及解决方案

1. CommandLineRunner执行顺序问题

在项目中可能会有多个CommandLineRunner实现类,SpringBoot在执行CommandLineRunner的时候并没有给出特定的执行顺序,所以需要开发者来指定使用@Order注解进行指定执行顺序。如下所示:

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

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

2. CommandLineRunner无法被单元测试覆盖到问题

由于CommandLineRunner是Spring容器启动之后执行的代码,而在单元测试中,启动Spring容器是无法将CommandLineRunner的代码也由JUnit所控制。对于这种情况,可以使用Spring-boot-starter-test提供的“TestResttemplate”来模拟外部调用,从而触发CommandLineRunner的执行流程。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CommandLineRunnerTests {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testCommandLineRunner() {
        // 模拟外部调用
        ResponseEntity<String> response = restTemplate.getForEntity("/", String.class);
        assertThat(response.getStatusCode().value()).isEqualTo(200);
    }
}

示例

接下来我们用示例来演示如何使用CommandLineRunner,以及如何应对上述两个坑点。

示例1

  1. 创建CommandLineRunner1
@Component
@Order(1)
public class CommandLineRunner1 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner1");
    }
}
  1. 创建CommandLineRunner2
@Component
@Order(2)
public class CommandLineRunner2 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner2");
    }
}
  1. 启动测试

启动Spring Boot应用程序并观察控制台输出,你会看到输出的顺序为:

CommandLineRunner1
CommandLineRunner2
  1. 结论

通过添加@Order(1)和@Order(2)注释,可以按照指定的顺序运行CommandLineRunner。

示例2

  1. 创建CommandLineRunner类
@Component
public class CommandLineRunnerImpl implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner execute success.");
    }
}
  1. 创建测试类
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CommandLineRunnerTests {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void test() {
        ResponseEntity<String> response = restTemplate.getForEntity("/", String.class);
        assertThat(response.getStatusCode().value()).isEqualTo(200);
    }
}
  1. 控制器设置
@RestController
public class IndexController {
    @GetMapping("/")
    public String index() {
        return "Hello, world!";
    }
}
  1. 启动测试

启动JUnit测试并观察控制台输出,你可以看到运行"CommandLineRunner execute success."的信息,并且可以进行正常的HTTP调用!

总结

在使用Spring Boot的CommandLineRunner时,要注意以上两个坑。使用@Order注解可以解决多个CommandLineRunner类的执行顺序问题, TestRestTemplate类可以模拟外部调用来触发CommandLineRunner接口的执行流程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用SpringBoot的CommandLineRunner遇到的坑及解决 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • Android实现城市选择三级联动

    Android实现城市选择三级联动攻略 在Android开发中,有时会需要实现城市选择功能,而且还需要支持三级联动,即选择省份后展示该省份下的市区列表,选择城市后展示该城市下的县区列表。这里提供一份Android实现城市选择三级联动的攻略。 一、搭建数据源 实现城市选择三级联动首先需要有一个完整的城市数据源,可以采用第三方库提供的数据,也可以自己搭建。以下是…

    C 2023年5月23日
    00
  • 浅谈C++的语句语法与强制数据类型转换

    下面是关于“浅谈C++的语句语法与强制数据类型转换”的完整攻略。 1. 首先了解C++的语句语法 在C++中,语句(Statement)是一组用于表达特定运算符或功能的代码,它们一般以分号(;)结尾。例如: int a = 5; // 声明一个整型变量a,并将其初始化为5 cout << "Hello"; // 输出Hello…

    C 2023年5月22日
    00
  • x86汇编DOS编程环境搭建过程

    搭建x86汇编DOS编程环境 1.安装DOSBox DOSBox是一个模拟DOS环境的开源软件,可以在现代操作系统上运行DOS程序。我们可以利用其模拟DOS环境来进行汇编语言程序的编写和调试。 在DOSBox官网上下载适用于你所使用操作系统的DOSBox并安装。 2.下载并安装x86汇编编译器 这里将介绍NASM。 下载NASM:http://www.nas…

    C 2023年5月23日
    00
  • C语言指针比较

    下面我将为您详细讲解C语言指针比较的完整使用攻略。 什么是C语言指针比较 在C语言中,指针比较可以用来比较两个指针变量指向的地址大小。指针变量在比较时,会将其指向的地址转为一个整数,然后进行比较。指针比较有三种情况,即<、>和==。 指针比较的注意事项 在进行指针比较时,需要注意以下几点: 两个指针变量指向的地址必须在同一块内存中。 对空指针进行…

    C 2023年5月9日
    00
  • C语言 数据结构与算法之字符串详解

    C语言 数据结构与算法之字符串详解 什么是字符串 在计算机科学中,字符串(string)是由零个或多个字符组成的有限序列,它是编程语言中的一种数据类型。在C语言中,字符串通常被看作是由字符组成的一维字符数组,以 ‘\0’(NUL)字符作为字符串的结束标志。 字符串的表示 在C语言中,字符串可以使用字符数组表示,例如: char str[10] = &quot…

    C 2023年5月23日
    00
  • android解析JSON数据

    Android解析JSON数据的完整攻略包括以下几个步骤: 1. 引入JSON库 Android提供了许多JSON库,例如GSON和Jackson等等。引入这些库需要在build.gradle文件中添加相应的依赖项,例如在build.gradle (Module:app)文件中添加以下代码: dependencies { // GSON库 implement…

    C 2023年5月23日
    00
  • 分享常用的3个C++小技巧

    下面是“分享常用的3个C++小技巧”的完整攻略: 1. 使用RAII技术自动释放资源 RAII(Resource Acquisition Is Initialization)是C++中的一项技术,它的思想是:当一个对象被创建时,它的构造函数会自动申请所需要的资源;当这个对象被销毁时,它的析构函数会自动释放申请的资源。利用RAII技术可以确保在任何时候都不会忘…

    C 2023年5月24日
    00
  • Javascript OOP之面向对象

    JavaScript OOP之面向对象 在JavaScript中,面向对象编程是一种非常强大的技术。通过面向对象编程,我们可以将代码进行高效的封装和组织,便于后期的维护和扩展。 基本概念 在面向对象编程中,有三个基本概念:类、对象和方法。 类 类是一种抽象的数据类型,它描述了一类对象的属性和方法。比如,一个类可以是“人”,它包含了“姓名”、“年龄”、“性别”…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部