我有一个Spring Boot应用程序,我正在使用Spring AMQP。我需要在ApplicationContext
结束事件上实现我自己的自定义逻辑,所以我在我的bean中实现了DisposableBean
,如下所示:
public class ShutdownHandler implements DisposableBean {
@Override
public void destroy() throws Exception {
// I need access message listener containers here
}
}
问题是当我运行我的代码时,所有AMQP bean已经关闭,我收到以下异常:
The ApplicationContext is closed and the ConnectionFactory can no longer create connections.
主要是,我需要将消息从某些队列移动到其他队列,以便在我的应用程序再次启动时恢复处理。
我发现问题是由于AbstractMessageListenerContainer
的相位设置为Integer.MAX_VALUE所以它将作为第一个应用程序上下文bean之一处理。
我尝试了什么(没有成功):
@DependsOn("listenerContainer")
注释SmartLifecycle
并设置阶段Integer.MAX_VALUE 您是否了解在应用程序上下文关闭阶段强制执行订单的其他方法并且可以访问Spring AMQP bean?
答案 0 :(得分:0)
在上下文销毁期间,您不应与其他bean交互。
连接工厂(你收到错误的地方是阶段Integer.MIN_VALUE + 1000
,这意味着它是stopped()
的最后一个bean(phase
与bean无关销毁令。)
而不是实施DisposableBean
,而是实施SmartLifecycle
。将bean放在比连接工厂大的阶段。
如果需要,您还可以更改侦听器容器的阶段。
所以,只要你的bean的阶段大于连接工厂,你的第二个选项应该有效 - 该消息仅在工厂停止后发出(这是一个非常早期的阶段 - 因此很晚才停止)。 / p>
您可以通过启用org.springframework
的DEBUG日志记录来观察bean停止顺序。如果您仍然无法弄清楚什么是错的,请在某处发布DEBUG日志并显示您的监听器和工厂配置。
答案 1 :(得分:0)
通过实施ApplicationListener<ContextClosedEvent>
,我找到了一个更简单的解决方案。该事件在应用程序上下文关闭的最初阶段和处理bean之前就被解雇了,这就是我所需要的。