使用Spring Boot 的CommandLineRunner遇到的坑
启动时失败
原因
CommandLineRunner的run方法是单线程执行的,当存在时间过长或多个线程执行时,有可能遇到阻塞会停止
解决办法
开启新的线程进行执行
@Component
public class ScheduleJobInitListener implements CommandLineRunner {
@Autowired
TaskService scheduleJobService;
@Override
public void run(String... arg0) throws Exception {
new Thread() {
public void run() {
try {
scheduleJobService.initSchedule();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
执行成功,打包失败,显示JdbcSQLException: not found table ‘XXX’
经过网上的搜查,显示提示这个错误的原因是字段写错,或大小写异常。但与碰到的问题不一样。我进行了如下筛查:
- 先行确认代码是否存在编写错误;
- 大小写问题;
- 将测试类打包注释掉,通过。
原因
commandLineRunner会在测试时自行加载。导致测试失败。启动新的线程也会报错。但加上睡眠时间就会发现正常了。故测试时CommandLineRunner先于表加载
@Override
public void run(String... arg0) throws Exception {
new Thread() {
public void run() {
try {
sleep(1000);
scheduleJobService.initSchedule();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
解决办法
经过网上的查找找到一种方式:在引CommandLineRunner的类上加注解@Profile("!test")进行排除测试类。具体可以在测试的配置文件中加spring.profiles.active=test
@Component
@Profile("!test")
public class ScheduleJobInitListener implements CommandLineRunner {
@Autowired
TaskService scheduleJobService;
@Override
public void run(String... arg0) throws Exception {
new Thread() {
public void run() {
try {
scheduleJobService.initSchedule();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}