網頁

2020/8/30

Spring Boot RabbitMQ @RabbitListener 簡單範例

Spring Boot RabbitMQ除了自行配置MessageListenerContainer及註冊MessageListener來收訊息外,也可使用@RabbitListener標註在方法上使其接收RabbitMQ的訊息。


本範例修改自Spring Boot Messaging with RabbitMQ 範例。參考範例設定RabbitMQ server及建立Spring Boot RabbitMQ專案。


Receiver.receiveMessage()前加上@RabbitListener,並設定監聽的queue名稱,則此方法會接受RabbitMQ的queue訊息。

Receiver

package com.abc.demo.mq.receiver;

import com.abc.demo.mq.config.RabbitMqConfig;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.concurrent.CountDownLatch;

@Component
public class Receiver {

    @RabbitListener(queues = RabbitMqConfig.QUEUE_NAME)
    public void receiveMessage(String message) {
        System.out.println("Received message:" + message);
    }

}

RabbitMqConfig配置RabbitMQ的queue,exchange及兩者間的binding。因為改用@RabbitListener指定接收訊息的方法,所以移除了MessageListenerContainer及註冊MessageListener的相關設定。

RabbitMqConfig

package com.abc.demo.mq.config;

import com.abc.demo.mq.receiver.Receiver;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {

    public static final String TOPIC_EXCHANGE_NAME = "demo-exchange";

    public static final String QUEUE_NAME = "demo-queue";

    public static final String ROUTING_KEY = "demo-routing-key";

    @Bean
    Queue queue() {
        return new Queue(QUEUE_NAME, false);
    }

    @Bean
    TopicExchange exchange() {
        return new TopicExchange(TOPIC_EXCHANGE_NAME);
    }

    @Bean
    Binding binding(Queue queue, TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY);
    }

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

}

MessageService,注入RabbitTemplate來發送訊息。

MessageService

package com.abc.demo.service;

import com.abc.demo.mq.config.RabbitMqConfig;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

@Service
public class MessageService {

    private final RabbitTemplate rabbitTemplate;

    public MessageService(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send(String message) throws Exception {
        System.out.println("Sending message:" + message);
        rabbitTemplate.convertAndSend(
                RabbitMqConfig.TOPIC_EXCHANGE_NAME,
                RabbitMqConfig.ROUTING_KEY,
                message);
    }
}


建立DemoController以REST API測試。test()中呼叫MessageService.send()並傳入路徑變數。

DemoController

package com.abc.demo.controller;

import com.abc.demo.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @Autowired
    private MessageService messageService;

    @GetMapping("/test/{message}")
    public void test(@PathVariable String message) throws Exception {
        messageService.send(message);
    }

}

啟動專案,使用Postman呼叫API GET | http://localhost:8080/demo/test/helloworld,在console會印出下面訊息

Sending message:helloworld
Received message:helloworld

參考github


沒有留言:

張貼留言