本章节将介绍通过实现 CommandLineRunner 和 ApplicationRunner 接口,实现 Spring Boot 启动成功初始化数据。
如果你有一些资源需要在 Spring Boot 启动成功后才去加载,如:预加载配置、加载定时任务、初始化工作等。这些可以通过 Spring Boot 给我们提供的CommandLineRunner 接口和 ApplicationRunner 接口实现。
CommandLineRunner 接口
CommandLineRunner接口是在容器启动成功后的最后一步回调(类似开机自启动)。接口的源码如下:
package org.springframework.boot;
@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
该接口只定义了一个 run() 方法,且该方法仅仅接收一个字符串数组。如果我们需要在 Spring Boot 启动成功后做些什么,如:初始化数据,需要实现该接口,实现 run 方法。例如:
package com.huangx.springboot.service;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
/**
* SpringBoot启动完成后自动运行
*/
@Service
public class AfterServiceStartedOther implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("AfterServiceStartedOther");
for(String arg : args) {
System.out.println(arg);
}
}
}
在运行 Spring Boot 时,添加参数,如下图:
程序运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
从上面实例可以知道,run 方法的参数实际是上就是我们运行程序传递的参数。
ApplicationRunner 接口
CommandLineRunner接口和ApplicationRunner 接口基本一样,区别在于两者接收的参数不一样。CommandLineRunner 的参数是最原始的参数,没有做任何处理;而ApplicationRunner的参数是ApplicationArguments,对原始参数做了进一步的封装。下面通过实例进行说明:
package com.huangx.springboot.service;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import java.util.Arrays;
/**
* SpringBoot启动完成后自动运行
*/
@Service
public class AfterServiceStarted implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("AfterServiceStarted");
for(String name : args.getOptionNames()) {
System.out.println(name + "=" + args.getOptionValues(name));
}
}
}
假如我们在这里配置了一些启动参数 --env=dev --level=debug,如下图:
然后运行程序,结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
如果使用 CommandLineRunner 实现上面实例,则 CommandLineRunner 只获取 --env=dev --level=debug 字符串。而 ApplicationRunner 可以将 --env=dev --level=debug 解析为 Key-Value,使得我们可以直接通过 key 来获取 value。
注意:ApplicationRunner 解析的参数必须使用“--”开头(双横线),否则不会解析。
设置 CommandLineRunner 和 ApplicationRunner 接口启动顺序
CommandLineRunner 和 ApplicationRunner 接口的工作方式类似,如果有多个启动回调接口实现类,我们还可以通过添加 @Order 注解指定顺序。
例如,我们将上面的 AfterServiceStarted 设置为第一个启动,AfterServiceStartedOther 设置为第二个启动。如下:
AfterServiceStarted.java
package com.huangx.springboot.service;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import java.util.Arrays;
/**
* SpringBoot启动完成后自动运行
*/
@Order(1)
@Service
public class AfterServiceStarted implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("AfterServiceStarted");
for(String name : args.getOptionNames()) {
System.out.println(name + "=" + args.getOptionValues(name));
}
}
}
AfterServiceStartedOther.java
package com.huangx.springboot.service;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/**
* SpringBoot启动完成后自动运行
*/
@Order(2)
@Service
public class AfterServiceStartedOther implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("AfterServiceStartedOther");
for(String arg : args) {
System.out.println(arg);
}
}
}
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|