简体   繁体   English

如何使用自动装配的Spring Boot监听多个队列?

[英]How to listen to multiple queues with autowired Spring Boot?

I'm new to Spring boot and I'm playing around with it. 我是Spring的新手,我正在玩它。 Currently I've build some apllications that I want to be able to communicate with each other through queues. 目前我已经构建了一些我希望能够通过队列相互通信的应用程序。 I currently have a Listener object that can receive message from a particular queue. 我目前有一个Listener对象,可以从特定队列接收消息。

@Configuration
public class Listener {

    final static String queueName = "myqueue";

    @Bean
    SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(queueName);
        container.setMessageListener(listenerAdapter);
        return container;
    }

    @Bean
    Receiver receiver() {
        return new Receiver();
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }
}

This works. 这有效。 However, now I want to be able to listen to another queue. 但是,现在我希望能够收听另一个队列。 So I figured I'd copy the above object and change the queue name. 所以我想我会复制上面的对象并更改队列名称。 Unfortunately this did not work as Spring boot only creates a connection for one of them. 不幸的是,这不起作用,因为Spring引导只为其中一个创建连接。 Any ideas on how I can have my Spring Boot application listen to multiple queues? 关于如何让我的Spring Boot应用程序听到多个队列的任何想法?

Ok, I figured out how to get it to listen to multiple queues. 好的,我想出了如何让它听多个队列。 Think there might be some downsides compared to my other solution, mainly that it doesn't work if the queue listed does not exist. 认为与我的其他解决方案相比可能存在一些缺点,主要是如果列出的队列不存在则不起作用。 I ended up using a totally different approach using a @RabbitListener 我最终使用了一个完全不同的方法,使用@RabbitListener

@Component
public class EventListener {

    private static Logger LOG = LoggerFactory.getLogger(EventListener.class);
    private CountDownLatch latch = new CountDownLatch(1);

    @RabbitListener(queues = "myqueue")
    public void processPaymentMessage(Object message) {
        LOG.info("Message is of type: " + message.getClass().getName());
        if(!(message instanceof byte[])) message = ((Message) message).getBody();
        String content = new String((byte[])message, StandardCharsets.UTF_8);
        LOG.info("Received on myqueue: " + content);
        latch.countDown();
    }

    @RabbitListener(queues = "myotherqueue")
    public void processOrderMessage(Object message) {
        LOG.info("Message is of type: " + message.getClass().getName());
        if(!(message instanceof byte[])) message = ((Message) message).getBody();
        String content = new String((byte[])message, StandardCharsets.UTF_8);           
        LOG.info("Received on myotherqueue: " + content);
        latch.countDown();
    }   
}

The whole check on byte[] is in there because that what a message send from the commandline looks like. 对byte []的整个检查就在那里,因为从命令行发送的消息看起来像。 Otherwise it's a org.springframework.amqp.core.Message. 否则它是一个org.springframework.amqp.core.Message。

You can try this 你可以试试这个

In application.properties 在application.properties中

rabbitmq.queue.names= com.queue1,com.queue2

In Java file 在Java文件中

@RabbitListener(queues = "#{'${rabbitmq.queue.names}'.split(',')}")
public void receiveMessage(Message message) {
    try {
        if (processmessage(message)); 
        }
    } catch (Exception ex) {
        LOGGER.error("Exception while processing the Message", ex);
    }

}

Here's what worked for me in groovy: 这是在groovy中对我有用的东西:

@Component
@EnableRabbit
@Slf4j
class StatusListener {
    Library library
    int messageCounter

    @Autowired
    StatusListener(Library library) {
        this.library = library
    }

    @RabbitListener(queues = '#{library.allStatusQueues.split(",")}')
    void receiveMessage(Message message) {
        messageCounter++
        log.info("Rabbit Listener received message <" + new String(message.body) + "> (" + messageCounter + ")")
    }
}

Where Library is a configuration bean: 其中Library是配置bean:

@Component
@ConfigurationProperties
@RefreshScope
class Library {
    String allStatusQueues
}

The property itself, in application.properties or similar config file looks like: application.properties或类似的配置文件中的属性本身如下所示:

all-status-queues=queue1,queue2,queue3,queue4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM