在运行时构造@RabbitListener 的最简单方法

Easiest way to construct @RabbitListener at runtime

在运行时构造它的最简单方法是什么?

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(value = "providedAtRuntime", durable = "true"),
    exchange = @Exchange(value = "providedAtRuntime", ignoreDeclarationExceptions = "true"),
    key = "providedAtRuntime"), containerFactory = "cFac")
public class RabbitProcessor {
    @RabbitHandler
    public void receive (String smth){
        System.out.println(smth);
    }
}

我想定义侦听器,但在运行时提供交换、队列名称和绑定。此外,此侦听器不应自动启动,而是在由 start() 方法调用时启动。同时它应该自动声明绑定和队列等。当调用 stop() 时,它应该停止消费。

我认为注释不可能,但您可以创建自定义 SimpleMessageListenerContainer

这是一个简单的解决方案:

public static AbstractMessageListenerContainer startListening(RabbitAdmin rabbitAdmin, Queue queue, Exchange exchange, String key, MessageListener messageListener) {
    rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(key).noargs());
    SimpleMessageListenerContainer listener = new SimpleMessageListenerContainer(rabbitAdmin.getRabbitTemplate().getConnectionFactory());
    listener.addQueues(queue);
    listener.setMessageListener(messageListener);
    listener.start();

    return listener;
}

你可以这样称呼它:

ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);

 ConnectionFactory connectionFactory = ctx.getBean(ConnectionFactory.class);
 RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
 AbstractMessageListenerContainer container = startListening(rabbitAdmin, rabbitAdmin.declareQueue(),
         new DirectExchange("amq.direct"), "testRoute", message -> {
             System.out.println(new String(message.getBody()));
         });

你可以

AbstractMessageListenerContainer.destroy()AbstractMessageListenerContainer.stop() 它。

Tested with spring boot 1.5.8.RELEASE and RabbitMQ 3.6.10