一 简单定义

用一个注解就可以接受MQ了,而不用定义交换机,定义队列啥的,简简单单,一句话搞定

@Component
public class MyService {

@RabbitListener(queues = "myQueue")
public void processOrder(String data) {
    ...
}
}

二 再复杂一点

一个默认队列怎么能满足要求能,当然是要实用点的

@Component
public class MyService {
  //定义队列名称,交换机名称,以及routingkey名称
  @RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "myQueue", durable = "true"),
        exchange = @Exchange(value = "auto.exch", ignoreDeclarationExceptions = "true"),
        key = "orderRoutingKey")
  )
  public void processOrder(Order order) {
    ...
  }
  
  //定义一个默认队列,监听所有的bindingkey
  @RabbitListener(bindings = @QueueBinding(
        value = @Queue,
        exchange = @Exchange(value = "auto.exch"),
        key = "invoiceRoutingKey")
  )
  public void processInvoice(Invoice invoice) {
    ...
  }
  
  //queue是个变量了,可以从配置文件中取到
  @RabbitListener(queuesToDeclare = @Queue(name = "${my.queue}", durable = "true"))
  public String handleWithSimpleDeclare(String data) {
      ...
  }  
}

我们还可以加入更多的参数,比如死信队列

@RabbitListener(
        bindings = @QueueBinding(
            value = @Queue(value = "annoQueue", durable = "true",
                    arguments = {
                        @Argument(name = "x-dead-letter-exchange", value = "dlx.exchange"),
                        @Argument(name = "x-dead-letter-routing-key", value = "dlx.routing.key")
            }),
            exchange = @Exchange(value = "annoExch", ignoreDeclarationExceptions = "true"),
            key = "annoKey"
      )
)
public void processOrder(Message msgStr, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long ta) throws Exception {
...
}

上述代码不仅定义了一个队列,并在argument中加入了死信队列,来接受失败消息
同时,我们在接受参数时 传入了 channel以及 tag, 这样可以很方便的进行消息回传了,比如: channel.baskAck(...)

三 元注解

有时候我们实在嫌写注解太麻烦了,可以定义一个元注解

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@RabbitListener(bindings = @QueueBinding(
        value = @Queue,
        exchange = @Exchange(value = "metaFanout", type = ExchangeTypes.FANOUT)))
public @interface MyAnonFanoutListener {
}

public class MetaListener {

    @MyAnonFanoutListener
    public void handle1(String foo) {
        ...
    }

    @MyAnonFanoutListener
    public void handle2(String foo) {
        ...
    }

}

四 默认监听连接工厂

有一点忘记说了,你如果确实想用@RabbitListener必须在@Configuration注解加上@EnableRabbit注解,比如这样

@Configuration
@EnableRabbit
public class AppConfig {

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory());
        factory.setConcurrentConsumers(3);
        factory.setMaxConcurrentConsumers(10);
        return factory;
    }
}

其中SimpleRabbitListenerContainerFactory是监听器的factory,如果你不指定,boot会自动生成一个出来,当然还是自己指定一个比较好。

五 连环发送

当你收到消息后想发到另一个队列该怎么办呢?可以用sendto注解

@RabbitListener(destination = "myQueue")
@SendTo("status")
public Message<OrderStatus> processOrder(Order order) {
    // order processing
    return MessageBuilder
        .withPayload(status)
        .setHeader("code", 1234)
        .build();
}







方老司
2k 声望224 粉丝

教育皆祸害,[链接]