@Payload
表示有效的传输数据
每个 RabbitTemplate
只支持一个
ReturnCallback
批次消息
BatchingRabbitTemplate
只有当一个批次完成才会向 RabbitMQ
发送消息
从1.4.2版本开始,引入了 BatchingRabbitTemplate
,它是 RabbitTemplate
的子类,覆盖了 send
方法,此方法可根据 BatchingStrategy
来批量发送消息;只有当一个批次完成时才会向 RabbitMQ
发送消息。
public interface BatchingStrategy {
MessageBatch addToBatch(String exchange, String routingKey, Message message);
Date nextRelease();
Collection<MessageBatch> releaseBatches();
}
警告
成批的数据是保存在内存中的,如果出现系统故障,未发送的消息将会丢失。
@RabbitListener
可以用在类上,监听多个方法
注意,如果有必要,需要在每个方法上指定 @SendTo
,在类级上它是不支持的。
检测空闲异步消费者
从1.6版本开始,当没有消息投递时,可配置监听器容器来发布 ListenerContainerIdleEvent
事件。当容器是空闲的,事件会每隔 idleEventInterval
毫秒发布事件。
要配置这个功能,须在容器上设置 idleEventInterval
:
- xml
<rabbit:listener-container connection-factory="connectionFactory"...idle-event-interval="60000"...
>
<rabbit:listener id="container1" queue-names="foo" ref="myListener" method="handle" />
</rabbit:listener-container>
- Java
@Bean
public SimpleMessageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
...
container.setIdleEventInterval(60000L);
...
return container;
}
@RabbitListener
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(rabbitConnectionFactory());
factory.setIdleEventInterval(60000L);
...
return factory;
}
事件消费
通过实现 ApplicationListener
可捕获这些事件- 要么是一个一般的监听器,要么是一个窄化的只接受特定事件的监听器。 你也可以使用Spring Framework 4.2中引入的 @EventListener
。
下面的例子在单个类中组合使用了 @RabbitListener
和 @EventListener
。重点要理解,应用程序监听器会收到所有容器的事件,因此如果你只对某个容器采取措施,那么你需要检查监听器id。你也可以使用 @EventListener
条件来达到此目的。
事件有4个属性:
source
- 监听容器实例id
- 监听器id(或容器bean名称)idleTime
- 当事件发布时,容器已经空闲的时间queueNames
- 容器监听的队列名称
public class Listener {
@RabbitListener(id="foo", queues="#{queue.name}")
public String listen(String foo) {
return foo.toUpperCase();
}
@EventListener(condition = "event.listenerId == 'foo'")
public void onApplicationEvent(ListenerContainerIdleEvent event) {
...
}
}
重要
事件监听器会查看所有容器的事件,因此,在上面的例子中,我们根据监听器ID缩小了要接收的事件。
警告
如果你想使用idle事件来停止监听器容器,你不应该在调用监听器的线程上来调用
container.stop()
方法- 它会导致延迟和不必要的日志消息。 相反,你应该把事件交给一个不同的线程,然后可以停止容器。
评论