赞
踩
两者本质上是同级的,比如监听了同一个queue,那么生产者发到这个queue的消息会轮询这两个消费方式。
不同的点是**@RabbitListener注解想实现手动ack必须在配置文件中配置**:
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: manual
增加配置后才可以在代码中进行手动ack:
@Component
public class DirectListenerOne {
@RabbitListener(queues = "TestDirectQueue")//监听的队列名称 TestDirectQueue
public void process(Message testMessage, Channel channel, @Headers Map<String, Object> map) {
System.out.println("One DirectReceiver消费者收到消息 : " + testMessage.toString());
//RabbitListener与ChannelAwareMessageListener同时basicReject情况测试
/*try {
channel.basicReject(testMessage.getMessageProperties().getDeliveryTag(), true);
} catch (IOException e) {
e.printStackTrace();
}*/
}
}
否则会报unknown delivery tag 1
的错误,就是因为rabbitmq的默认ack是自动的,如果在代码中手动reject,那么就相当于ack了两次,那么第二次肯定就会找不到delivery。
而ChannelAwareMessageListener一般是配合SimpleMessageListenerContainer一起使用,通过在配置文件中配置实现:
@Configuration public class MessageListenerConfig { @Autowired private CachingConnectionFactory connectionFactory; @Autowired private MyAckListener myAckListener;//消息接收处理类 @Bean public SimpleMessageListenerContainer simpleMessageListenerContainer() { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setConcurrentConsumers(1); container.setMaxConcurrentConsumers(1); container.setAcknowledgeMode(AcknowledgeMode.MANUAL); // RabbitMQ默认是自动确认,这里改为手动确认消息 //设置一个队列 container.setQueueNames("TestDirectQueue"); //如果同时设置多个如下: 前提是队列都是必须已经创建存在的 // container.setQueueNames("TestDirectQueue","TestDirectQueue2","TestDirectQueue3"); //另一种设置队列的方法,如果使用这种情况,那么要设置多个,就使用addQueues //container.setQueues(new Queue("TestDirectQueue",true)); //container.addQueues(new Queue("TestDirectQueue2",true)); //container.addQueues(new Queue("TestDirectQueue3",true)); container.setMessageListener(myAckListener); return container; } }
channel.basicNack(deliveryTag, false, true);
channel.basicReject(deliveryTag, true); 拒绝消费当前消息,如果第二参数传入true,就是将数据重新丢回队列里,那么下次还会消费这消息。设置false,就是告诉服务器,我已经知道这条消息数据了,因为一些原因拒绝它,而且服务器也把这个消息丢掉就行。 下次不想再消费这条消息了。
@RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用
@RabbitListener 标注在类上面表示当有收到消息的时候,就交给 @RabbitHandler 的方法处理,具体使用哪个方法处理,根据 MessageConverter 转换后的参数类型
@Component
@RabbitListener(queues = "consumer_queue")
public class Receiver {
@RabbitHandler public void processMessage1(String message) { System.out.println(message); }
@RabbitHandler public void processMessage2(byte[] message) { System.out.println(new String(message)); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。