hello,你们好,我是小黑,又和你们见面啦~~java
若是你去某度搜索关键词 CommandLineRunner 初始化资源
,截止小黑同窗写这篇推文以前,大概能收到 1,030,000
个结果。app
网上大部分的文章都在告诉咱们说可使用 CommandLineRunner
去初始化资源,但几乎不多有文章告诉咱们:若是 CommandLineRunner
使用不当,就会致使程序出现一些奇怪的异常,更有可能致使咱们的应用直接中止运行。ide
正在读这篇文章的你若是也使用了 CommandLineRunner
去初始化资源,那么小黑同窗劝你耗子尾汁,赶忙来看一下下面这些案例吧~测试
@Slf4j @SpringBootApplication public class CommandLineRunnerDemoApp { private Map<String, String> map; public static void main(String[] args) { SpringApplication.run(CommandLineRunnerDemoApp.class, args); } @RestController public class controller { @GetMapping("/name") public String name() { return map.get("name"); } } @Bean public CommandLineRunner commandLineRunner() { return args -> { // 模拟加载数据过慢 log.info("start do commandLineRunner..."); TimeUnit.MINUTES.sleep(1); map = ImmutableMap.of("namne", "coder小黑"); log.info("do commandLineRunner end"); }; } }
Spring 容器启动以后,访问 http://localhost:8080/name
,此时后台就会直接报错:3d
经过报错信息咱们能够知道:日志
CommandLineRunner
在 Spring 容器起来以后开始执行,但此时 Tomcat 已经能够正常接收请求。又因为本案例中 CommandLineRunner 的运行时间过长,数据尚未初始化完成,因而程序就开始出错了......code
那若是 CommandLineRunner
在执行过程当中报错了会怎么样呢?blog
答案是:Spring 容器会自动关闭,应用会中止服务。资源
可能读者会反驳小黑同窗说:“CommandLineRunner
在启动时运行,若是 CommandLineRunner
运行报错,那就发布失败呗。”get
其实还有更严重的......
废话很少说,直接上具体案例,先看代码:
@Slf4j @SpringBootApplication public class CommandLineRunnerDemoApp2 implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(CommandLineRunnerDemoApp2.class, args); } @Override public void run(String... args) throws Exception { log.info("start do commandLineRunner..."); // 模拟任务执行时长 TimeUnit.MINUTES.sleep(1); // 模拟运行过程当中出错 int i = 1 / 0; log.info("do commandLineRunner end"); } }
运行日志以下:
能够看到,Spring 容器一开始正常运行,系统开始对外提供服务。一分钟以后,CommandLineRunner
在执行过程当中报错,致使 Spring 容器关闭,应用中止服务。
虽然上文中这些案例都很简单,但小黑同窗在实际过程当中,还真就遇到过有同窗使用 CommandLineRunner
去初始化了一个很耗时的资源,而在初始化资源的时候,又不当心报错了,因而应用就忽然中止了。不过幸运的是,此次只是发生在了测试环境,线上一切正常。