该版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring AMQP 3.2.6spring-doc.cadn.net.cn

检测空闲异步使用者

虽然高效,但异步消费者的一个问题是检测它们何时空闲——用户可能希望 如果一段时间内没有消息到达,则执行一些作。spring-doc.cadn.net.cn

从 1.6 版开始,现在可以配置侦听器容器以发布ListenerContainerIdleEvent当一段时间过去没有消息传递时。 当容器处于空余状态时,每隔一次就会发布一个事件idleEventInterval毫秒。spring-doc.cadn.net.cn

要配置此功能,请将idleEventInterval在容器上。 以下示例显示了如何在 XML 和 Java 中执行此作(对于SimpleMessageListenerContainerSimpleRabbitListenerContainerFactory):spring-doc.cadn.net.cn

<rabbit:listener-container connection-factory="connectionFactory"
        ...
        idle-event-interval="60000"
        ...
        >
    <rabbit:listener id="container1" queue-names="foo" ref="myListener" method="handle" />
</rabbit:listener-container>
@Bean
public SimpleMessageListenerContainer smlc(ConnectionFactory connectionFactory) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
    ...
    container.setIdleEventInterval(60000L);
    ...
    return container;
}
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(rabbitConnectionFactory());
    factory.setIdleEventInterval(60000L);
    ...
    return factory;
}

在每种情况下,当容器处于空闲状态时,每分钟发布一次事件。spring-doc.cadn.net.cn

事件消耗

您可以通过实现ApplicationListener——要么是普通听众,要么是缩小到仅听众 接收此特定事件。 您还可以使用@EventListener,在 Spring Framework 4.2 中引入。spring-doc.cadn.net.cn

以下示例将@RabbitListener@EventListener到单个类中。 您需要了解应用程序侦听器获取所有容器的事件,因此您可能需要 如果要根据哪个容器处于空闲状态执行特定作,请检查侦听器 ID。 您还可以使用@EventListener condition为此目的。spring-doc.cadn.net.cn

事件有四个属性:spring-doc.cadn.net.cn

以下示例演示了如何使用@RabbitListener@EventListener附注:spring-doc.cadn.net.cn

public class Listener {

    @RabbitListener(id="someId", queues="#{queue.name}")
    public String listen(String foo) {
        return foo.toUpperCase();
    }

    @EventListener(condition = "event.listenerId == 'someId'")
    public void onApplicationEvent(ListenerContainerIdleEvent event) {
        ...
    }

}
事件侦听器可以看到所有容器的事件。 因此,在前面的示例中,我们根据侦听器 ID 缩小了接收到的事件范围。
如果您希望使用 idle 事件来停止列表器容器,则不应调用container.stop()在调用侦听器的线程上。 这样做总是会导致延迟和不必要的日志消息。 相反,您应该将事件移交给可以停止容器的其他线程。