Spring Boot Series 13 Spring Boot Integration RabbitMQ

Keywords: RabbitMQ Spring Java github

1. overview

Before I had A series of articles on RabbitMQ This article introduces the use of RabbitMQ, and how to integrate RabbitMQ in Spring Boot. The main contents of this paper are as follows:

  • demo of two ways of sending and receiving messages in Springboot
  • Configuration uses MessageConverter to serialize messages

2. Introduction to the Public Section of Demo Engineering

Project Name: rabbitmq

New jar s need to be introduced into pom.xml in our project

 Sprboot: This version uses amqp-client version 4.x, all need to comment out the above amqp-client configuration - >
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-amqp</artifactId>
 </dependency>

Configure application-boot.yml

spring:
  # Configure rabbitMQspring:
  rabbitmq:
    host: 10.240.80.134
    username: spring-boot
    password: spring-boot
    virtual-host: spring-boot-vhost

The following code is in this project

3. Simple Application demo 1

3.1. RabbitConfigure2

@Configuration
public class RabbitConfigure2 {

    // Queue name
    public final static String SPRING_BOOT_QUEUE = "spring-boot-queue-2";
    // Switch name
    public final static String SPRING_BOOT_EXCHANGE = "spring-boot-exchange-2";
    // Bound values
    public static final String SPRING_BOOT_BIND_KEY = "spring-boot-bind-key-2";
}

3.2. Send messages

By default, AmqpAdmin and AmqpTemplate are generated in spring boot for us to interact with RabbitMQ.
The default instance of AmqpTemplate is Rabbit Template, and the default instance of AmqpAdmin is Rabbit Admin. The source code shows that its internal implementation is actually Rabbit Template. So AmqpAdmin and AmqpTemplate are essentially the same

Sender code: SendMsg2

@Component
public class SendMsg2 {

    // This interface has only one default implementation, RabbitAdmin, and its internal implementation is actually RabbitTemplate through source code discovery. So AmqpAdmin and AmqpTemplate are essentially the same at the moment.
    @Autowired
    private AmqpAdmin amqpAdmin;

    // The default implementation of this interface is RabbitTemplate, which currently has only one implementation.
    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * send message
     *
     * @param msgContent
     */
    public void send_2(String msgContent) {
        amqpTemplate.convertAndSend(RabbitConfigure2.SPRING_BOOT_EXCHANGE, RabbitConfigure2.SPRING_BOOT_BIND_KEY, msgContent);
    }
}

3.3. Receive messages:

The method of receiving a message through the @RabbitListener annotation, which can be defined

  • QueueBinding: Defines the message binding to be listened for this time
  • Queue: Define the queue. If RabbitMQ does not have this queue, create it. If it has the same configuration parameters, ignore it or throw an exception.
  • Exchange: Define the switch. If RabbitMQ does not have this switch, create it. If it has the same configuration parameters, ignore it or throw an exception.

Receiver code: ReceiveMsg2

@Component
public class ReceiveMsg2 {

    /**
     * === Create queue,exchange,binding method 2 on RabbitMQ: declare begin === directly on @RabbitListener
     * Receive
     * @param content
     */
    @RabbitListener(containerFactory = "rabbitListenerContainerFactory",
            bindings = @QueueBinding(
            value = @Queue(value = RabbitConfigure2.SPRING_BOOT_QUEUE+"3", durable = "true", autoDelete="true"),
            exchange = @Exchange(value = RabbitConfigure2.SPRING_BOOT_EXCHANGE, type = ExchangeTypes.TOPIC),
            key = RabbitConfigure2.SPRING_BOOT_BIND_KEY)
    )
    public void receive_2(String content) {
        // ...
        System.out.println("[ReceiveMsg-2] receive msg: " + content);
    }

}

3.4. Startup class and test class

Startup class: SpringBootRabbitApplication2
Test class: SimpleTest2

@RunWith(SpringRunner.class)
@SpringBootTest(classes= SpringBootRabbitApplication2.class, value = "spring.profiles.active=boot")
public class SimpleTest2 {

    @Autowired
    private ReceiveMsg2 receiveMsg2;

    @Autowired
    private SendMsg2 sendMsg2;

    @Test
    public void sendAndReceive_2(){
        String testContent = "send msg via spring boot -2";
        sendMsg2.send_2(testContent);
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

Output result

[ReceiveMsg-2] receive msg: send msg via spring boot -2

4. Simple Application demo 2

4.1. RabbitConfigure1

In the first example, we declare queues, switches, binding relationships on the @RabbitListener annotation, where we use @Bean to declare this object. See Rabbit Configure1 for details

@Configuration
public class RabbitConfigure1 {

    // Queue name
    public final static String SPRING_BOOT_QUEUE = "spring-boot-queue-1";
    // Switch name
    public final static String SPRING_BOOT_EXCHANGE = "spring-boot-exchange-1";
    // Bound values
    public static final String SPRING_BOOT_BIND_KEY = "spring-boot-bind-key-1";


    // ==== Create queue,exchange,binding method 1 on RabbitMQ: implement begin==== through @Bean
    /**
     * Define queues:
     * @return
     */
    @Bean
    Queue queue() {
        return new Queue(SPRING_BOOT_QUEUE, false);
    }

    /**
     * Define switches
     * @return
     */
    @Bean
    TopicExchange exchange() {
        return new TopicExchange(SPRING_BOOT_EXCHANGE);
    }

    /**
     * Define binding
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    Binding binding(Queue queue, TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(SPRING_BOOT_BIND_KEY );
    }

4.2. Message Receiving Class

Receiving classes still use @RabbitListener, but only queues need to be configured, queues support regular matching as well as perfect matching

Message Receiving Class: ReceiveMsg1

@Component
public class ReceiveMsg1 {

    /**
     * Access to information:
     *  queue Fuzzy matching of queues in RabbitMQ can also be supported.
     * @param content
     */
    @RabbitListener(queues = RabbitConfigure1.SPRING_BOOT_QUEUE)
    public void receive_1(String content) {
        // ...
        System.out.println("[ReceiveMsg-1] receive msg: " + content);
    }

}

4.3. Test class:

SimpleTest
output

[ReceiveMsg-1] receive msg: send msg via spring boot - 1

5. Configure MessageConverter's Demo in RabbitMQ

In the previous example, we used String to send and receive messages. Here we can set the method parameters of sending and receiving messages by setting MessageConverter.

5.1. Testing POJO

MsgContent1 and MsgContent2 The simplest POJO classes are private attributes and set/get methods

5.2. Setting the serialization class RabbitMsgConvertConfigure

Similar to the previous demo, in addition to using @Bean to declare queues, switches, and binding relationships, there are many methods to initialize MessageConverter () by Jackson 2JsonMessageConverter, which is injected into the RabbitListener Container container for transforming messages sent and received.

RabbitMsgConvertConfigure

@Configuration
public class RabbitMsgConvertConfigure {
    /**
     * Define an instance of message transformation
     * @return
     */
    @Bean
    MessageConverter jackson2JsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
….
}

5.3. Message sender:

Send messages, send objects directly here
Message sender: SendMsgConvertMsg

@Component
public class SendMsgConvertMsg {

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * send message
     *
     * @param msgContent
     */
    public void sendMsgContent1(MsgContent1 msgContent) {
        amqpTemplate.convertAndSend(RabbitMsgConvertConfigure.SPRING_BOOT_EXCHANGE, RabbitMsgConvertConfigure.SPRING_BOOT_BIND_KEY, msgContent );

    }

    /**
     * send message
     * @param msgContent
     */
    public void sendMsgContent2(MsgContent2 msgContent) {
        amqpTemplate.convertAndSend(RabbitMsgConvertConfigure.SPRING_BOOT_EXCHANGE, RabbitMsgConvertConfigure.SPRING_BOOT_BIND_KEY, msgContent);
    }
}

5.4. Message Receiver:

RabbitListener is defined in a class to indicate that this class is a message listener and to set up a queue to listen on
RabbitHandler: Multiple @RabbitHandler can be defined in the class, and spring boot is passed to different methods based on different parameters.

Message Receiver: ReceiveMsgConvertMsg

@Component
// RabbitListener works on classes as well as methods. In the latter case, you need to use @RabbitHandler in the processing method. A class can configure multiple @RabbitHandler
@RabbitListener(queues = RabbitMsgConvertConfigure.SPRING_BOOT_QUEUE)
public class ReceiveMsgConvertMsg {

    /**
     * Access to information:
     *  queue Fuzzy matching of queues in RabbitMQ can also be supported.
     * @param content
     */
    @RabbitHandler
    public void receiveMsgContent1(MsgContent1 content) {
        // ...
        System.out.println("[ReceiveMsgConvertMsg-MsgContent1] receive receiveMsgContent1 msg: " + content);
    }

    @RabbitHandler
    public void receiveMsgContent2(MsgContent2 msgContent2) {
        // ...
        System.out.println("[ReceiveMsgConvertMsg-MsgContent2] receive receiveMsgContent2 msg: " + msgContent2);
    }
}

Test class: MsgConvertTest

Output result

[ReceiveMsgConvertMsg-MsgContent1] receive receiveMsgContent1 msg: [ name = send msg via spring boot - msg convert - MsgContent1;  age = 27 ]
[ReceiveMsgConvertMsg-MsgContent2] receive receiveMsgContent2 msg: [ id = 83;  content = send msg via spring boot - msg convert - MsgContent1 ]

6. code

See the github code for all the details. Please use it as much as possible. tag v0.17, don't use master, because master keeps changing, and there's no guarantee that the code in this article will always be the same as that on github.

Posted by rlgriffo on Sun, 23 Dec 2018 01:45:06 -0800