簡體   English   中英

如何使用自動裝配的Spring Boot監聽多個隊列?

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

我是Spring的新手,我正在玩它。 目前我已經構建了一些我希望能夠通過隊列相互通信的應用程序。 我目前有一個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");
    }
}

這有效。 但是,現在我希望能夠收聽另一個隊列。 所以我想我會復制上面的對象並更改隊列名稱。 不幸的是,這不起作用,因為Spring引導只為其中一個創建連接。 關於如何讓我的Spring Boot應用程序聽到多個隊列的任何想法?

好的,我想出了如何讓它聽多個隊列。 認為與我的其他解決方案相比可能存在一些缺點,主要是如果列出的隊列不存在則不起作用。 我最終使用了一個完全不同的方法,使用@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();
    }   
}

對byte []的整個檢查就在那里,因為從命令行發送的消息看起來像。 否則它是一個org.springframework.amqp.core.Message。

你可以試試這個

在application.properties中

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

在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);
    }

}

這是在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 + ")")
    }
}

其中Library是配置bean:

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

application.properties或類似的配置文件中的屬性本身如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM