用途
测试Spring Boot应用程序时,有的人习惯写测试用例,有的人习惯写Controller,手动调用进行测试。有时候我会使用 CommandLineRunner
或 ApplicationRunner
进行测试。测试的方法很简单,直接让SpringBoot启动类 (带有 @SpringBootApplication
的类) 实现 CommandLineRunner
或 ApplicationRunner
并实现它的方法,运行项目即可。
使用CommandLineRunner 示例如下:
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Autowired
private MyService myService;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
myService.doBusiness();
}
}
使用ApplicationRunner示例如下:
@SpringBootApplication
public class DemoApplication implements ApplicationRunner {
@Autowired
private MyService myService;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
myService.doBusiness();
}
}
那么这两个接口有什么不同呢?
通过观察,可以发现run方法的参数列表不同。
@FunctionalInterface
public interface ApplicationRunner {
void run(ApplicationArguments args) throws Exception;
}
@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
CommandLineRunner
CommandLineRunner.run()接收String数组作为参数
在工程中添加如下组件
@Component
public class CommandLineRunnerBean implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(String.join(", ", args));
}
}
有两种方式设置参数
1、 将工程打包,使用java -jar运行,并设定参数
java -jar demo-0.0.1-SNAPSHOT.jar ni hao shi jie
运行结果
2021-03-29 17:48:07.196 INFO 11140 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-03-29 17:48:07.681 INFO 11140 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.874 seconds (JVM running for 1.295)
ni, hao, shi, jie
ni hao shi jie
是设定的4个参数,在命令行中参数之间以空格隔开,CommandLineRunner的实现类中将参数拼接并输出
2、无需打包,在IDEA中 Run → Edit Configurations → 展开Environment,设置Program arguments
运行结果
2021-03-29 17:45:31.416 INFO 10292 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-03-29 17:45:31.831 INFO 10292 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.712 seconds (JVM running for 1.329)
--age=12, --name=张三, --name=李四, 测试
ApplicationRunner
ApplicationRunner在某些情况下功能更强大,可以使用key来获取value
ApplicationRunner # run()
的参数类型 ApplicationArguments
public interface ApplicationArguments {
String[] getSourceArgs();
Set<String> getOptionNames();
boolean containsOption(String name);
List<String> getOptionValues(String name);
List<String> getNonOptionArgs();
}
在工程中添加如下组件
@Component
public class ApplicationRunnerBean implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("containsOption : " + args.containsOption("age"));
System.out.println("nonOptionArgs : " + String.join(",", args.getNonOptionArgs()));
System.out.println("sourceArgs : " + String.join(",", Arrays.asList(args.getSourceArgs())));
System.out.println("optionNames : " + String.join(",", args.getOptionNames()));
System.out.println("optionValues : " + String.join(",", args.getOptionValues("name")));
}
}
本示例不再演示打包运行,仅在IDE中设置参数并运行
program arguments : --age=12 --name=张三 --name=李四 测试
运行结果
2021-03-29 18:05:07.223 INFO 4108 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-03-29 18:05:07.663 INFO 4108 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.73 seconds (JVM running for 1.265)
containsOption : true
nonOptionArgs : 测试
sourceArgs : --age=12,--name=张三,--name=李四,测试
optionNames : name,age
optionValues : 张三,李四
通过运行结果即可了解 ApplicationArguments
各个方法的作用
public interface ApplicationArguments {
// 根据key判断是否包含某个参数
boolean containsOption(String name);
// 没有key的value
List<String> getNonOptionArgs();
// 获取原始参数
String[] getSourceArgs();
// 获取参数的key
Set<String> getOptionNames();
// 获取参数的value
List<String> getOptionValues(String name);
}