RabbitMQ's subscription mode, routing mode and wildcard mode are integrated with spring

RabbitMQ is divided into two parts: one is the switch (dealing with the sender) and the other is the queue (dealing with the listener) No matter which working mode, the sender will only send the data to the switch, and then the switch will send it to the queue, and then the queue will send it to the listener, or the listener detects that there is data in the queue and needs to bind the queue to the switch to complete the operation of sending and receiving messages. If the queue is not bound to the switch, there will be no messages in the queue
The entry mode of RabbitMQ and the default switch used at the bottom of the queue working mode bind queues in the default way, that is, send to all queues. If tens of thousands of requests are sent in the actual project, the default switch will send these data to each queue, which will cause the service corresponding to a queue to receive unnecessary data, so To specify the switch, the designated switch official wrote us three commonly used pub/sub subscription modes, routing routing mode and wildcard mode

Pub/Sub subscription mode
Manually specify the binding relationship between the switch and the queue. For example, station b pays attention to an up master. When the up updates a post, all users who pay attention to it must receive the post. Those who do not pay attention must not be allowed to receive it

routing mode
This working mode should not only specify the relationship between the switch and the queue, but also set the same key for the switch and the queue. Suppose that when the up Master of station b sends the post, it can be set that the large members of station b who only pay attention to it can see it, and the ordinary members who pay attention to it can't see it. Then it is set that only the up master and the large members can see it. This can't be realized according to the setting of subscription mode A routing mode needs to wear a key when binding the switch to the queue, so we can judge whether to send it to the user through this key

Topics wildcard pattern
There is a problem with the routing mode. Assuming that we are large members and pay attention to a lot of UPS, we have to write the key many times. Assuming that the key starts with a and does not take into account other situations, this is an example. Following this idea, it will be troublesome for us to write the key many times every time. In this case, we can use the Topics wildcard working mode. The wildcard indicates that only one hypothetical key can be matched. The key is a.1.2.3 Then use the wildcard A. in this way, it will not match a.1.2.3. It can only match a.1. Such a key wildcard # means that multiple a. # can be matched to a.1.2.3

Integrate spring related dependencies

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.amqp</groupId>
        <artifactId>spring-rabbit</artifactId>
        <version>2.1.8.RELEASE</version>
    </dependency>

Sender related spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:rabbit="http://www.springframework.org/schema/rabbit"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   https://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/rabbit
   http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

<!--Load profile-->
<context:property-placeholder location="classpath:rabbitmq.properties"/>

<!-- definition rabbitmq connectionFactory -->
<rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
                           port="${rabbitmq.port}"
                           username="${rabbitmq.username}"
                           password="${rabbitmq.password}"
                           virtual-host="${rabbitmq.virtual-host}"/>
<!--Define management switches, queues-->
<rabbit:admin connection-factory="connectionFactory"/>

<!--Define a persistent queue. If it does not exist, it will be created automatically; Bind to default switch if not bound to switch
 The default switch type is direct,The name is:"",The routing key is the name of the queue
-->
<!--
    id: bean Name of
    name: queue Name of
    auto-declare:Automatic creation
    auto-delete:Automatically delete. When the last consumer disconnects from the queue, the queue is automatically deleted
    durable: Persistent
-->

<rabbit:queue id="spring_queue" name="spring_queue"    auto-declare="true"/>

<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~radio broadcast; All queues can receive messages~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!--Define the persistent queue in the broadcast switch. If it does not exist, it will be created automatically-->
<rabbit:queue id="spring_fanout_queue_1" name="spring_fanout_queue_1" auto-declare="true"/>

<!--Define the persistent queue in the broadcast switch. If it does not exist, it will be created automatically-->
<rabbit:queue id="spring_fanout_queue_2" name="spring_fanout_queue_2" auto-declare="true"/>

<!--Define broadcast type switch; And bind the above two queues-->
<rabbit:fanout-exchange id="spring_fanout_exchange" name="spring_fanout_exchange"  auto-declare="true">
    <rabbit:bindings>
        <rabbit:binding  queue="spring_fanout_queue_1"  />
        <rabbit:binding queue="spring_fanout_queue_2"/>
    </rabbit:bindings>
</rabbit:fanout-exchange>


<!-- Define queue-->
<rabbit:queue id="spring_direct_queue" name="spring_direct_queue"  auto-declare="true"/>

<!--
  definition Routing  Routing mode interactive machine
-->
<rabbit:direct-exchange name="spring_direct_exchange" >
    <rabbit:bindings>
        <!--direct Switch binding queue of type  key : route key  queue: Queue name-->
        <rabbit:binding queue="spring_direct_queue" key="info"></rabbit:binding>
    </rabbit:bindings>

</rabbit:direct-exchange>

<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~Wildcards;*Match a word,#Match multiple words
<!--Define the persistent queue in the broadcast switch. If it does not exist, it will be created automatically-->
<rabbit:queue id="spring_topic_queue_star" name="spring_topic_queue_star"  auto-declare="true"/>
<!--Define the persistent queue in the broadcast switch. If it does not exist, it will be created automatically-->
<rabbit:queue id="spring_topic_queue_well" name="spring_topic_queue_well" auto-declare="true"/>
<!--Define the persistent queue in the broadcast switch. If it does not exist, it will be created automatically-->
<rabbit:queue id="spring_topic_queue_well2" name="spring_topic_queue_well2" auto-declare="true"/>

<!--
  statement  topic Type of switch
-->
<rabbit:topic-exchange id="spring_topic_exchange"  name="spring_topic_exchange" auto-declare="true">
    <rabbit:bindings>
        <rabbit:binding pattern="baiqi.*"  queue="spring_topic_queue_star"/>
        <rabbit:binding pattern="baiqi.#" queue="spring_topic_queue_well"/>
        <rabbit:binding pattern="itcast.#" queue="spring_topic_queue_well2"/>
    </rabbit:bindings>
</rabbit:topic-exchange>

<!--definition rabbitTemplate Object operation can easily send messages in code-->
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>

classpath:rabbitmq.properties configuration file

rabbitmq.host=192.168.1.104  # ip address of RabbitMQ
rabbitmq.port=5672	     # Port to send data to RabbitMQ
rabbitmq.username=guest      # RabbitMQ login account
rabbitmq.password=guest      # RabbitMQ login password
rabbitmq.virtual-host=/baiqi  # Virtual machine name

spring sender code

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-rabbitmq-producer.xml")    // Load a spring configuration file
public class ProducerTest {

//1. Inject rabbit template
@Autowired
private RabbitTemplate rabbitTemplate;


@Test
public void testHelloWorld(){    // Entry mode
    //2. Send message

    rabbitTemplate.convertAndSend("spring_queue","hello world sp455445547ring....");
}


/**
 * Send fanout message
 */
@Test
public void testFanout(){      // The switch in subscription mode is of fanout type
    //2. Send message
    rabbitTemplate.convertAndSend("spring_fanout_exchange","","spring fanout....");
}


@Test
public void testDirect(){      // The switch in routing mode is of direct type
    //2. Send message

    rabbitTemplate.convertAndSend("spring_direct_exchange","info","spring Direct....");
}

/**
 * Send topic message
 */
@Test
public void testTopics(){      // The switch in Wildcard mode is of direct type
    //2. Send message

    rabbitTemplate.convertAndSend("spring_topic_exchange","baiqi.hehe.haha","spring topic....");
}

}

Listener correlation

spring configuration file

	<?xml version="1.0" encoding="UTF-8"?>
		<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/rabbit
       http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
    <!--Load profile-->
    <context:property-placeholder location="classpath:rabbitmq.properties"/>

    <!-- definition rabbitmq connectionFactory -->
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
                               port="${rabbitmq.port}"
                               username="${rabbitmq.username}"
                               password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.virtual-host}"/>

    <bean id="springQueueListener" class="com.baiqi.rabbitmq.listener.SpringQueueListener"/>   // Just look at this one. What is annotated below is that the class names are different
    <!--<bean id="fanoutListener1" class="com.baiqi.rabbitmq.listener.FanoutListener"/>
    <bean id="fanoutListener2" class="com.baiqi.rabbitmq.listener.FanoutListener2"/>
    <bean id="topicListenerStar" class="com.baiqi.rabbitmq.listener.TopicListenerStar"/>
    <bean id="topicListenerWell" class="com.baiqi.rabbitmq.listener.TopicListenerWell"/>
    <bean id="topicListenerWell2" class="com.baiqi.rabbitmq.listener.TopicListenerWell2"/>
-->
    <rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">     // Create a long connection of listener type
       <rabbit:listener ref="springQueueListener" queue-names="spring_queue"/>                 // Queue names the listener only deals with the queue and only needs to write the queue name, because the association relationship is established at the sender
        <rabbit:listener ref="fanoutListener1" queue-names="spring_fanout_queue_1"/>
        <!--<rabbit:listener ref="fanoutListener2" queue-names="spring_fanout_queue_2"/>
        <rabbit:listener ref="topicListenerStar" queue-names="spring_topic_queue_star"/>
        <rabbit:listener ref="topicListenerWell" queue-names="spring_topic_queue_well"/>
        <rabbit:listener ref="topicListenerWell2" queue-names="spring_topic_queue_well2"/>-->
    </rabbit:listener-container>
</beans>

monitor

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;

public class SpringQueueListener implements MessageListener {    // As long as you override the onMessage method under the pretext of implementing MessageListener, you can listen to the queue
    @Override
    public void onMessage(Message message) {     // Message here is the message
        //Print message
        System.out.println(new String(message.getBody()));
    }
}

Listener test class

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {
    //Initialize the IOC container so that it can listen to the messages in the queue. The association relationships are mapped in the spring configuration file
    ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring-rabbitmq-consumer.xml");


}

}

Keywords: RabbitMQ Spring

Added by soianyc on Sat, 15 Jan 2022 02:45:08 +0200