一 简单定义
用一个注解就可以接受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 processOrder(Order order) {
// order processing
return MessageBuilder
.withPayload(status)
.setHeader("code", 1234)
.build();
}