Spring Boot integrates ActiveMQ

There are two main types of asynchronous messages in ActiveMQ: queue and topic. Queue is used for point-to-point message communication and topic is used for publish / subscribe message communication.
ActiveMQ installation:
Baidu online disk download: https://pan.baidu.com/s/1BNoOeiZ_Ry0oe-raEEVEmA
Extraction code: 3qba
Official website: http://activemq.apache.org/
Installation:
Enter the road
double-clickAfter the startup is successful, the result connector VM: / / localhost started as shown in the figure will appear
Enter http://127.0.0.1:8161/admin/ in the browser to access the server of ActiveMQ. The user name and password are admin/admin. As follows:
We can see that there are two options, Queues and Topics, which are the view window of point-to-point message and publish / subscribe message respectively
ActiveMQ integration
To integrate ActiveMQ in Spring Boot, you need to import the following starter dependency:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

Then in the application.yml configuration file, configure activemq as follows:

spring:
  activemq:
    broker-url: tcp://localhost:61616
    in-memory: true
    pool:
      # If this is set totrue,Need to add activemq-pool Otherwise, automatic configuration will fail, unable to inject JmsMessagingTemplate
      enabled: false
server:
  port: 8080

Queue and Topic are two messaging models supported by JMS:
1. Point to point (PTP) Queue messaging model:
With this messaging model, one application (message producer) can send messages to another application (message consumer). In this delivery model, the message Destination type is queue (that is, the Destination interface implementation class instance is created by the Session interface implementation class instance by calling its createQueue method and passing in the queue name). Messages are first delivered to a specific queue on the message server side, and then from this pair of columns, messages are delivered to a consumer listening on this queue. The same queue can be associated with multiple message producers and message consumers, but a message can only be delivered to one message consumer. If multiple message consumers are listening to messages on the queue, the JMS message server determines which message consumer receives the next message based on the first come first principle. If no message consumer is listening to the queue, the message remains in the queue until the message consumer connects to the queue. This kind of messaging model is the lazy model or polling model in the traditional sense. In this model, the message is not automatically pushed to the message consumer, but is requested from the queue by the message consumer.
2. publish/subscribe Topic messaging model:
With this messaging model, an application can send a message to multiple message consumers. In this delivery model, the message Destination type is the topic (that is, the Destination interface implementation class instance is created by the Session interface implementation class instance by calling its createTopic method and passing in the topic name). The message is first published by the message producer to a specific topic in the message server, and then delivered by the message server to all consumers who have subscribed to the topic. Theme goals also support long-term subscriptions. A long-term subscription indicates that the consumer has registered a topic target, but that the consumer can be inactive when the message reaches the target. When the consumer is active again, the message is received. If none of the consumers have registered a topic target, the topic only keeps messages of inactive consumers who have registered for long-term subscription. Unlike the PTP messaging model, the pub/sub messaging model allows multiple subject subscribers to receive the same message. JMS keeps messages until they are received by all subject subscribers. The pub/sub messaging model is basically a push model. In this model, messages are broadcast automatically, and consumers do not need to obtain new messages by actively requesting or polling topics.
Creation of Queue and Topic
First, we need to create two kinds of messages: Queue and Topic. To create these two kinds of messages, we put them into ActiveMqConfig, as follows:

import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;

import javax.jms.ConnectionFactory;
import javax.jms.Destination;
@Configuration
public class ActiveMqConfig {
    /**
     * Publish / subscribe mode queue name
     */
    public static final String TOPIC_NAME = "activemq.topic";
    /**
     * Point to point mode queue name
     */
    public static final String QUEUE_NAME = "activemq.queue";

    @Bean
    public Destination topic() {
        
        return new ActiveMQTopic(TOPIC_NAME);
    }

    @Bean
    public Destination queue() {
        return new ActiveMQQueue(QUEUE_NAME);
    }

Message sender:

import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.jms.Destination;
@Service
public class MsgProducer {

    @Resource
    private JmsMessagingTemplate jmsMessagingTemplate;
	
    public void sendMessage(Destination destination, String msg) {
        jmsMessagingTemplate.convertAndSend(destination, msg);
    }
}

Point to point message production and consumption

@RestController
@RequestMapping("/activemq")
public class ActiveMqController {

    private static final Logger logger = LoggerFactory.getLogger(ActiveMqController.class);

    @Resource
    private MsgProducer producer;
    @Resource
    private Destination topic;
    @Resource
    private Destination queue;

    @GetMapping("/send/queue")
    public String sendQueueMessage() {
        logger.info("===Start sending point-to-point messages===");
        producer.sendMessage(queue, "Queue: hello activemq!");
        return "success";
    }

Point to point message consumption

@Service
public class QueueConsumer {

    /**
     * Receive point-to-point messages
     * @param msg
     */
    @JmsListener(destination = ActiveMqConfig.QUEUE_NAME)
    public void receiveQueueMsg(String msg) {
        System.out.println("The message received is:" + msg);
    }

Start the project, input: http://localhost:8081/activemq/send/queue in the browser, observe the output log of the console, and the following log appears to indicate that the message was sent and consumed successfully.

Production and consumption of publish / subscribe messages (topic)

@RestController
@RequestMapping("/activemq")
public class ActiveMqController {

    private static final Logger logger = LoggerFactory.getLogger(ActiveMqController.class);

    @Resource
    private MsgProducer producer;
    @Resource
    private Destination topic;

    @GetMapping("/send/topic")
    public String sendTopicMessage() {

        logger.info("===Start sending subscription message===");
        producer.sendMessage(topic, "Topic: hello activemq!");
        return "success";
    }
}

Solve the problem of receiving both queue message and topic message

   /**
     * 
     * Solve the problem of receiving both queue message and topic message
     */
    @Bean
    public JmsListenerContainerFactory topicListenerContainer(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        // Equivalent to configuration in application.yml: spring. JMS. Pub sub domain = true
        factory.setPubSubDomain(true);
        return factory;
    }

Topic message consumer (can support multiple consumers at the same time)

@Service
public class TopicConsumer1 {

    /**
     * Receive subscription message
     * @param msg
     * ,Specify this container factory in the @ JmsListener annotation to consume topic messages
     */
    @JmsListener(destination = ActiveMqConfig.TOPIC_NAME, containerFactory = "topicListenerContainer")
    public void receiveTopicMsg(String msg) {
        System.out.println("The message received was 1:" + msg);
    }

}
@Service
public class TopicConsumer2{

    /**
     * Receive subscription message
     * @param msg
     * ,Specify this container factory in the @ JmsListener annotation to consume topic messages
     */
    @JmsListener(destination = ActiveMqConfig.TOPIC_NAME, containerFactory = "topicListenerContainer")
    public void receiveTopicMsg2(String msg) {
        System.out.println("The message received was 2:" + msg);
    }

}

Test:

  @GetMapping("/send/topic")
    public String sendTopicMessage() {

        logger.info("===Start sending subscription message===");
//        Destination destination = new ActiveMQTopic(ActiveMqConfig.TOPIC_NAME);
        producer.sendMessage(topic, "Topic: hello activemq!");
        return "success";
    }

The message received is 1: Topic: hello activemq!
The message received is 2: Topic: hello activemq!
Persistent configuration of topic:

  @Bean(name = "topicContainerFactory1")
    public DefaultJmsListenerContainerFactory topicClient1(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer){
        DefaultJmsListenerContainerFactory factory = defaultJmsListenerContainerFactoryTopic(connectionFactory,configurer);
        factory.setConnectionFactory(connectionFactory);
        // Equivalent to configuration in application.yml: spring. JMS. Pub sub domain = true
        factory.setPubSubDomain(true);
        factory.setClientId("10001");
        return factory;
    }

    @Bean(name = "topicContainerFactory2")
    public DefaultJmsListenerContainerFactory topicClient2(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer){
        DefaultJmsListenerContainerFactory factory = defaultJmsListenerContainerFactoryTopic(connectionFactory,configurer);
        factory.setConnectionFactory(connectionFactory);
        // Equivalent to configuration in application.yml: spring. JMS. Pub sub domain = true
        factory.setPubSubDomain(true);
        factory.setClientId("10002");
        return factory;
    }
    public DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactoryTopic(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        configurer.configure(factory,connectionFactory);
        factory.setPubSubDomain(true);
        factory.setSessionTransacted(true);
        factory.setAutoStartup(true);
        //Open persistent subscription
        factory.setSubscriptionDurable(true);
        return factory;
    }
@JmsListener(destination = ActiveMqConfig.TOPIC_NAME,containerFactory = "topicContainerFactory1") // Listen to the specified message subject
    public void receiveMessage1(String message) throws Exception {
        System.out.println("The message received was 1:" + message);
    }

 @JmsListener(destination = ActiveMqConfig.TOPIC_NAME,containerFactory = "topicContainerFactory2") // Listen to the specified message subject
    public void receiveMessage1(String message) throws Exception {
        System.out.println("The message received was 2:" + message);
    }

Test reception:
Start the project first, and note the following receiving code to access http://localhost:8080/activemq/send/topic push message
Release the comment, restart the project, and you will receive the message just pushed

Reference: https://blog.csdn.net/eson_15/article/details/104347476
https://blog.csdn.net/Cons_Step_By_Step/article/details/78314826

Published 14 original articles, won praise 2, visited 1621
Private letter follow

Tags: Spring Apache Session

Posted on Sun, 23 Feb 2020 04:36:02 -0500 by Orio