Spring项目启动时,ApplicationRunner和CommandLineRunner的用法

本文介绍在Spring项目中如何通过实现ApplicationRunner或CommandLineRunner接口来控制启动时资源的初始化顺序,包括示例代码和具体实现方式。

Spring项目启动时,如果需要初始化资源,可以实现ApplicationRunner或者CommandLineRunner,并且可以使用注解@Order指定他们的运行顺序。

 

示例代码:https://github.com/rickding/HelloJava/tree/master/HelloRunner

3个类文件:

 

RunnerApplication.java实现SpringBootApplication主程序:

 

HelloApplicationRunner.java实现ApplicationRunner:

 

HelloCommandLineRunner.java实现CommandLineRunner,并且指定@Order(1):

 

输出日志:

 

参考文章:https://blog.youkuaiyun.com/qq_28804275/article/details/80891941

 

<think>好的,我现在要解决用户关于Spring Boot启动过程中ApplicationRunnerJms Listener监听Topic的执行顺序的问题。用户想知道这两者的执行顺序,我需要详细分析Spring Boot的启动流程,并找到相关的执行点。 首先,我需要回忆Spring Boot应用程序的启动过程。通常,Spring Boot启动时会创建ApplicationContext,初始化Bean,并执行各种Runner接口的实现,比如ApplicationRunnerCommandLineRunner。同时,JMS监听器,尤其是使用@JmsListener注解的,可能涉及消息监听容器的启动。 接下来,我需要确定这两个组件在启动过程中的执行顺序。根据Spring的文档,ApplicationRunner是在ApplicationContext完全刷新之后,在应用程序启动的最后阶段执行的。而JMS监听器,尤其是基于Spring的JMS监听容器(如DefaultMessageListenerContainer),通常会在Bean初始化的后期阶段启动,具体可能是在SmartLifecycle的实现中。 我记得SmartLifecycle接口中的start()方法会在ApplicationContext刷新完成后被调用,而ApplicationRunner的执行也是在刷新之后。但具体它们的顺序是怎样的?可能要看它们的phase值。默认情况下,ApplicationRunner可能是在最后阶段执行的,而消息监听容器的启动可能更早,或者在同一个阶段但顺序不同。 需要查阅相关资料或者Spring的源码来确定。例如,ApplicationRunner的执行是在SpringApplication的callRunners()方法中,而JMS监听容器的启动可能是在LifecycleProcessor中的启动阶段。如果消息监听容器的Lifecycle phase较低,那么它们会在ApplicationRunner之前启动。否则,可能在之后。 另外,可能要考虑@JmsListener注解的处理时机。当使用@EnableJms时,JmsListenerAnnotationBeanPostProcessor会在Bean初始化后处理这些注解,注册监听器。但监听器实际的启动可能是在上下文刷新完成后,由消息监听容器控制。 根据Spring Boot的启动流程,ApplicationRunner的执行是在刷新上下文之后,所有Bean准备就绪之后。而消息监听容器的启动可能是在上下文刷新阶段,作为Lifecycle组件启动。如果消息监听容器实现了SmartLifecycle,并且默认的phase是0,那么它们会在ApplicationRunner之前启动,因为ApplicationRunner的执行可能在更高phase的阶段。 比如,SmartLifecycle的默认phase是0,而ApplicationRunner的执行可能在更后的阶段。因此,可能JMS监听器会在ApplicationRunner之前启动并开始监听。但需要验证这一点。 可能需要查找相关的文档或源码。例如,在Spring Boot的SpringApplication类中,callRunners()方法是在afterRefresh()之后被调用的。而afterRefresh()是在上下文刷新之后执行的。同时,LifecycleProcessor的启动是在上下文刷新的最后阶段,即finishRefresh()方法中触发。而SmartLifecycle组件会根据phase顺序启动。 假设消息监听容器的Lifecycle phase较低,那么它们的start()会在callRunners()之前执行。因此,JMS监听器可能在ApplicationRunner之前就开始监听消息了。但如果有多个Lifecycle组件,它们的启动顺序由phase决定。 总结,可能的执行顺序是:Spring Boot启动 -> 初始化所有Bean -> 启动消息监听容器(作为SmartLifecycle组件) -> 执行ApplicationRunner的run方法。因此,JMS监听器会在ApplicationRunner之前开始运行,因此监听器可能先于ApplicationRunner执行。 不过,用户的问题是关于监听Topic的执行顺序,即当应用启动时,JMS监听器何时开始接收消息,而ApplicationRunner何时运行。如果监听器在ApplicationRunner之前启动,那么可能在ApplicationRunner执行前就已经可以处理消息了。但如果在ApplicationRunner之后,那么消息处理会在之后开始。 为了确认这一点,可能需要查看DefaultMessageListenerContainer的启动阶段。DefaultMessageListenerContainer实现了SmartLifecycle,默认的autoStartup为true,并且phase默认是0。而ApplicationRunner的执行是在SpringApplication的callRunners()阶段,该阶段在LifecycleProcessor启动之后。因此,Lifecycle组件(如消息监听容器)会在ApplicationRunner之前启动,导致JMS监听器在ApplicationRunner的run方法执行前就开始监听消息了。 因此,最终的结论是:在Spring Boot启动过程中,JMS监听器(如使用@JmsListener监听Topic的组件)会在ApplicationRunner执行之前开始运行,因此它们的初始化顺序更早,能够更早接收消息。</think>在Spring Boot启动过程中,`ApplicationRunner`JMS监听器的执行顺序可以通过以下流程分析: 1. **上下文初始化阶段** Spring Boot首先完成`ApplicationContext`的创建Bean的初始化。所有Bean(包括`@JmsListener`注解的监听器)在此阶段完成实例化,但尚未启动消息监听容器。 2. **上下文刷新完成阶段** 当`ApplicationContext`刷新完成后,Spring会触发`LifecycleProcessor`启动所有实现了`SmartLifecycle`接口的组件。**JMS监听容器(如`DefaultMessageListenerContainer`)默认实现了`SmartLifecycle`,其`phase`值为0**,因此会在此阶段自动启动并开始监听消息[^1]。 3. **ApplicationRunner执行阶段** 最后,Spring Boot调用所有`ApplicationRunner``CommandLineRunner`的实现类。**`ApplicationRunner`的执行发生在所有`SmartLifecycle`组件启动之后**,因此JMS监听器已处于活跃状态[^2]。 ### 执行顺序总结 $$启动顺序 = \text{JMS监听器启动} \rightarrow \text{ApplicationRunner执行}$$ ### 示例代码验证 ```java @Component public class DemoJmsListener { @JmsListener(destination = "test.topic") public void handleMessage(String message) { System.out.println("JMS监听器收到消息: " + message); } } @Component public class DemoApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { System.out.println("ApplicationRunner执行"); } } ``` 启动日志会显示: ``` JMS监听器启动... ApplicationRunner执行 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源码控

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值