用Spring Boot开发命令行执行程序

用Spring Boot开发命令行执行程序,第1张

通常使用Spring Boot,我们都是开发服务程序,是一种启动后就不停止的。如果想要用Spring Boot开发一次性执行的程序,该怎么设计呢?

基于Spring Boot,而不是纯粹的jdk开发一次性执行程序,有什么区别呢?那就是可以利用Springframework的特性都可以被使用。依赖反转、spring expression、日志、测试等都可以快速搭建起来。这不就是Spring Boot的宗旨吗?

首先从 Spring initializr 上创建一个最简单的Spring Boot项目,不需要添加任何依赖,就会生成类似下方的项目文件。

我们可以根据需要实现ApplicationRunner或CommandLineRunner接口,那么启动Spring Boot应用时就会执行我们的逻辑,并在全部执行结束后退出。

把程序跑起来我们就发现:

我们可以用 @Order(value= ?) 来调整不同Runner的执行顺序,可以达到我们的业务诉求。

我们从SpringApplication的run方法进入,可以找到这些Runner是如何被调用执行的。关键就在于

org.springframework.boot.SpringApplication#callRunners 方法,以及该方法内部的 org.springframework.core.annotation.AnnotationAwareOrderComparator 排序方法。跟踪到这个类的父类 org.springframework.core.OrderComparator 说明中,可以看到具体的排序规则:

覆盖了有Order,没Order的各种情况,包括使用 org.springframework.core.PriorityOrdered 注解的方式都统一在这个 java.util.Comparator 中定义和实现。

在实际应用中两种Runner有什么差异呢?仅仅差异在入参。可以详见 org.springframework.boot.CommandLineRunner 和 org.springframework.boot.ApplicationRunner 的定义。

建议用 ApplicationRunner ,因为不需要自己做命令参数解析,而且功能也完全覆盖 CommandLineRunner 。

举例子,看下方的输出即可。

出现这个问题的原因在于springboot添加了websocket组件,并且配置的时候开启了心跳包,心跳包和springboot定时器是配合使用的,在shutdown的时候tomcat会因为关闭顺序问题报错

registry.enableSimpleBroker("/queue","/topic","/user").setHeartbeatValue(new long[]{10000L, 10000L}).setTaskScheduler(new DefaultManagedTaskScheduler())

去掉心跳包配置即可

registry.enableSimpleBroker("/queue","/topic","/user")


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11733849.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存