RabbitMQ:@RabbitListener与@RabbitHandler及消息序列化

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天, 点击查看活动详情

一、@RabbitListener注解

@RabbitListener 注解来指定 某方法或者某类作为消息消费的方法 ,监听某 Queue 里面的消息。

@RabbitListener(queues = "${rabbitmq.queue}",
        containerFactory = "rabbitListenerContainerFactory")
@RabbitHandler
public void doReceivePassMsg(Message message, Channel channel) throws IOException{
    String body = new String(message.getBody());

也可以 通过 @RabbitListener 注解声明 Binding:@RabbitListener 的 bindings 属性声明 Binding,若 RabbitMQ 中不存在该绑定所需要的 Queue、Exchange、RouteKey 则自动创建若存在则抛出异常

@RabbitListener(bindings = @QueueBinding(
        exchange = @Exchange(value = "topic.exchange",durable = "true",type = "topic"),
        value = @Queue(value = "consumer_queue",durable = "true"),
        key = "key.#"
public void processMessage1(Message message) {
    System.out.println(message);

二、@RabbitHandler注解

@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));

三、MessageConvert消息序列化

RabbitMQ的序列化是指Message的body属性,即我们真正需要传输的内容,RabbitMQ 抽象出一个 MessageConvert接口处理消息的序列化,其实现有SimpleMessageConverter(默认)Jackson2JsonMessageConverter等。

当调用了convertAndSend方法时会使用MessageConvert进行消息的序列化; SimpleMessageConverter对于要发送的消息体body为byte[]时不进行处理 ,如果是String则转成字节数组,如果是Java对象,则使用jdk序列化将消息转成字节数组,转出来的结果较大,含class类名,类相应方法等信息。因此性能较差,当使用RabbitMQ作为中间件时,数据量比较大,此时就要考虑使用类似 Jackson2JsonMessageConverter等序列化形式以此提高性能

private SimpleRabbitListenerContainerFactory getSimpleRabbitListenerContainerFactory(@Qualifier("connectionFactoryPass") ConnectionFactory connectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    //使用jackson进行消息序列与反序列
    factory.setMessageConverter(new Jackson2JsonMessageConverter());
    // 开启手动 ack
    factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    factory.setDefaultRequeueRejected(false);
    return factory;

四、 @Payload与@Headers

使用 @Payload 和 @Headers 注解可以消息中的body 与 headers 信息。

@RabbitListener(queues = "debug")
public void processMessage1(@Payload String body, @Headers Map<String,Object> headers) {
    System.out.println("body:"+body);
    System.out.println("Headers:"+headers);
复制代码
分类:
后端
标签: