Actual Spring4+ActiveMQ integration to realize message queue (producer + consumer)

introduction:

Recently, the company has done a project focusing on information security. One of the business requirements is that the project regularly monitors the behavior of operating users. For some serious violations, an email alert is sent in the form of sending an email (FoxMail), which may be For multiple people, it may be one person. The first time is in the form of a single person. It is enough to send emails directly at the place where the business layer needs to be alerted. However, the requirements have changed later. For some alarm emails, multiple people may be sent. There may be the possibility of blocking the sending of emails, until all the emails are sent before continuing to do the following business. The leader said that this will affect the user experience. When sending emails, the user has been in a waiting state and cannot do other things. Finally, the research says to use a message queue. When there is a need to send an email alarm, a logo message is added to the queue. ActiveMQ monitors the hours in the queue in real time in the form of a listener. After receiving the message, it determines whether it is necessary to send an alarm. , if yes, you can send emails by yourself! This is the message queue ActiveMQ studied, and the following is the specific content:

1. ActiveMQ

1.1). ActiveMQ

 ActiveMQ is an open source message system provided by Apache, which is completely implemented in Java. Therefore, it can well support the JMS (Java Message Service, or Java Message Service) specification proposed by J2EE. JMS is a set of Java application program interfaces, which provides a series of services such as creation, sending, and reading of messages. JMS provides a set of common application program interfaces and response syntax, similar to the unified access interface JDBC of Java database. It is a vendor-independent API, which enables Java programs to communicate well with message components of different vendors.

1. 2). Java Message Service(JMS)

JMS supports two message sending and receiving models.

  • One is called P2P (Ponit to Point) model (point-to-point one-to-one), that is, sending messages in a point-to-point manner. The P2P model is based on queues. Message producers send messages to queues, and message consumers receive messages from queues. The existence of queues makes asynchronous transmission of messages possible. The P2P model is used in point-to-point message delivery.

  • The other is called Pub/Sub (Publish/Subscribe, that is, publish-subscribe) model. The publish-subscribe model defines how to publish and subscribe messages to a content node, which is called a topic. Topics can be thought of as intermediaries for message delivery, message publishing which publishes messages to a topic, and message subscribers subscribe to messages from the topic. Topic enables message subscribers and message publishers to remain independent of each other, and ensures message delivery without contact. The publish-subscribe model is used in one-to-many broadcast of messages.

1.3). JMS terminology
  1. Provider/MessageProvider: Producer
  2. Consumer/MessageConsumer: Consumer
  3. PTP: Point To Point, point-to-point communication message model
  4. Pub/Sub: Publish/Subscribe, publish-subscribe message model
  5. Queue: Queue, one of the target types, combined with PTP
  6. Topic: Topic, one of the target types, combined with Pub/Sub
  7. ConnectionFactory: The connection factory that JMS uses to create connections
  8. Connnection: the connection from JMS Client to JMS Provider
  9. Destination: message destination, created by Session
  10. Session: Session, created by Connection, is essentially a thread that sends and receives messages, so producers and consumers are created by Session
1.4). ActiveMQ application scenarios

Similar to express delivery , the courier (producer) can leave after placing the express (Message) at the designated place (destination), and the person who takes the express (customer) will go to the designated place (destination) to pick up the express after receiving the notice (Message) will do. Of course, you may need to authenticate when picking up the courier, which involves specifying a username and password when creating a connection. Also, in real life, when the courier puts the courier away, it stands to reason that the customer should be informed where to pick up the courier, and ActiveMq has done everything for us, and Activemq will help us realize the work of notification, without the need for us to code it ourselves To notify the consumer, the producer only needs to put the Message in Mq to notify the consumer of the work, and mq will help us deal with it

The purpose is to process messages, that is to say, JMS has in-depth applications in large e-commerce websites, such as JD.com, Taobao, Qunar and other websites. The main function of the queue is to eliminate high concurrent access peaks and speed up the response speed of the website.

In the case of not using the message queue, the user's request data is directly written to the database. In the case of high incidence, it will cause huge pressure on the database, and also aggravate the system response delay. However, after using the queue, the user's request is sent to the queue. Return immediately after.

1.5). ActiveMQ download

1.6). Start

Double-click the activemq.bat file in the /apache-activemq-5.15.3/bin/win64/ directory, enter http://localhost:8161/admin/ in the browser, and enter admin for the username and password

2. Srping+ActiveMQ application example

2,1). Project structure

** 2, 2). Import maven dependencies, pom.xml file**
  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4   <modelVersion>4.0.0</modelVersion>
  5 
  6   <groupId>www.cnblogs.com.hongmoshu</groupId>
  7   <artifactId>test_actmq</artifactId>
  8   <version>0.0.1-SNAPSHOT</version>
  9   <packaging>war</packaging>
 10   <name>test_actmq Maven Webapp</name>
 11   <url>http://www.example.com</url>
 12   
 13    <!-- 版本管理 -->
 14   <properties>
 15     <springframework>4.1.8.RELEASE</springframework>
 16   </properties>
 17  
 18 
 19    <dependencies>
 20    
 21      <!-- junit单元测试 -->
 22     <dependency>
 23       <groupId>junit</groupId>
 24       <artifactId>junit</artifactId>
 25       <version>4.11</version>
 26       <scope>test</scope>
 27     </dependency>
 28     
 29     <!-- JSP相关 -->
 30   <dependency>
 31     <groupId>jstl</groupId>
 32     <artifactId>jstl</artifactId>
 33     <version>1.2</version>
 34   </dependency>
 35   <dependency>
 36     <groupId>javax.servlet</groupId>
 37     <artifactId>servlet-api</artifactId>
 38     <scope>provided</scope>
 39     <version>2.5</version>
 40   </dependency>
 41 
 42      <!-- spring -->
 43     <dependency>
 44       <groupId>org.springframework</groupId>
 45       <artifactId>spring-core</artifactId>
 46       <version>${springframework}</version>
 47     </dependency>
 48     <dependency>
 49       <groupId>org.springframework</groupId>
 50       <artifactId>spring-context</artifactId>
 51       <version>${springframework}</version>
 52     </dependency>
 53     <dependency>
 54       <groupId>org.springframework</groupId>
 55       <artifactId>spring-tx</artifactId>
 56       <version>${springframework}</version>
 57     </dependency>
 58     <dependency>
 59       <groupId>org.springframework</groupId>
 60       <artifactId>spring-webmvc</artifactId>
 61       <version>${springframework}</version>
 62     </dependency>
 63     <dependency>
 64       <groupId>org.springframework</groupId>
 65       <artifactId>spring-jms</artifactId>
 66       <version>${springframework}</version>
 67     </dependency>
 68     
 69     <!-- xbean 如<amq:connectionFactory /> -->
 70     <dependency>
 71       <groupId>org.apache.xbean</groupId>
 72       <artifactId>xbean-spring</artifactId>
 73       <version>3.16</version>
 74     </dependency>
 75     
 76     <!-- activemq -->
 77     <dependency>
 78       <groupId>org.apache.activemq</groupId>
 79       <artifactId>activemq-core</artifactId>
 80       <version>5.7.0</version>
 81     </dependency>
 82     <dependency>
 83       <groupId>org.apache.activemq</groupId>
 84       <artifactId>activemq-pool</artifactId>
 85       <version>5.12.1</version>
 86     </dependency>
 87     
 88     <!-- gson -->
 89     <dependency>
 90       <groupId>com.google.code.gson</groupId>
 91       <artifactId>gson</artifactId>
 92       <version>1.7.1</version>
 93     </dependency>
 94     
 95       <!-- JSON -->
 96     <dependency>
 97         <groupId>net.sf.json-lib</groupId>
 98         <artifactId>json-lib</artifactId>
 99         <version>2.4</version>
100         <classifier>jdk15</classifier>
101     </dependency>
102     
103   </dependencies>
104 
105   <build>
106     <finalName>test_actmq</finalName>
107   
108   </build>
109 </project>
2,3). ActiveMQ configuration file ActiveMQ.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:amq="http://activemq.apache.org/schema/core"
 5        xmlns:jms="http://www.springframework.org/schema/jms"
 6        xmlns:context="http://www.springframework.org/schema/context"
 7        xmlns:mvc="http://www.springframework.org/schema/mvc"
 8        xsi:schemaLocation="
 9         http://www.springframework.org/schema/beans
10         http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
11         http://www.springframework.org/schema/context
12         http://www.springframework.org/schema/context/spring-context-4.1.xsd
13         http://www.springframework.org/schema/mvc
14         http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
15         http://www.springframework.org/schema/jms
16         http://www.springframework.org/schema/jms/spring-jms-4.1.xsd
17         http://activemq.apache.org/schema/core
18         http://activemq.apache.org/schema/core/activemq-core-5.12.1.xsd"
19 >
20 
21     <context:component-scan base-package="com.svse.service" />
22     <mvc:annotation-driven />
23 
24     <!-- jms.useAsyncSend=true 允许异步接收消息 -->
25     <amq:connectionFactory id="amqConnectionFactory"
26                            brokerURL="tcp://192.168.6.111:61616?jms.useAsyncSend=true"
27                            userName="admin"
28                            password="admin" />
29 
30     <!-- 配置JMS连接工 厂 -->
31     <bean id="connectionFactory"
32           class="org.springframework.jms.connection.CachingConnectionFactory">
33         <constructor-arg ref="amqConnectionFactory" />
34         <property name="sessionCacheSize" value="100" />
35     </bean>
36 
37     <!-- 定义消息队列名称(Queue) -->
38     <bean id="demoQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
39         <!-- 设置消息队列的名字 -->
40         <constructor-arg>
41             <value>Jaycekon</value>
42         </constructor-arg>
43     </bean>
44 
45     <!-- 配置JMS模板(Queue),Spring提供的JMS工具类,它发送、接收消息。 -->
46     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
47         <property name="connectionFactory" ref="connectionFactory" />
48         <property name="defaultDestination" ref="demoQueueDestination" />
49         <property name="receiveTimeout" value="10000" />
50         <!-- true是topic,false是queue,默认是false,此处显示写出false -->
51         <property name="pubSubDomain" value="false" />
52         <!-- 消息转换器 -->    
53         <property name="messageConverter" ref="userMessageConverter"/>  
54     </bean>
55 
56      <!-- 类型转换器 -->    
57     <bean id="userMessageConverter" class="com.svse.util.ObjectMessageConverter"/>    
58 
59 
60     <!-- 配置消息队列监听者(Queue) -->
61      <bean id="queueMessageListener" class="com.svse.util.QueueMessageListener" /> 
62 
63     <!-- 显示注入消息监听容器(Queue),配置连接工厂,监听的目标是demoQueueDestination,监听器是上面定义的监听器 -->
64     <bean id="queueListenerContainer"
65           class="org.springframework.jms.listener.DefaultMessageListenerContainer">
66         <property name="connectionFactory" ref="connectionFactory" />
67         <property name="destination" ref="demoQueueDestination" />
68         <property name="messageListener" ref="queueMessageListener" />
69     </bean> 
70     
71 </beans>
2,4). Spring's configuration file spring-mvc.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:mvc="http://www.springframework.org/schema/mvc"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7         http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/context
 9         http://www.springframework.org/schema/context/spring-context-4.1.xsd
10         http://www.springframework.org/schema/mvc 
11         http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
12          
13     <context:component-scan base-package="com.svse.controller" />
14     <mvc:annotation-driven />
15     <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
16         <property name="viewClass"
17             value="org.springframework.web.servlet.view.JstlView" />
18         <property name="prefix" value="/WEB-INF/views/" />
19         <property name="suffix" value=".jsp" />
20     </bean>
21      
22 </beans>
2.5). web.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 3          xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
 4          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
 5          id="WebApp_ID" version="3.1">
 6   <display-name>mydemo</display-name>
 7   
 8   <welcome-file-list>
 9     <welcome-file>index.jsp</welcome-file>
10   </welcome-file-list>
11   
12   <!-- 加载spring及active的配置文件,classpath为项目src下的路径 -->
13   <context-param>
14     <param-name>contextConfigLocation</param-name>
15     <param-value>
16           classpath:spring-mvc.xml;
17           classpath:ActiveMQ.xml;
18     </param-value>
19     </context-param>
20 
21 
22  <listener>
23     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
24   </listener>
25 
26   <servlet>
27     <servlet-name>springMVC</servlet-name>
28     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
29     <init-param>
30       <param-name>contextConfigLocation</param-name>
31       <param-value>classpath:spring-mvc.xml</param-value>
32     </init-param>
33     <load-on-startup>1</load-on-startup>
34   </servlet>
35   <servlet-mapping>
36     <servlet-name>springMVC</servlet-name>
37     <url-pattern>/</url-pattern>
38   </servlet-mapping>
39 
40   <!-- 处理编码格式 -->
41   <filter>
42     <filter-name>characterEncodingFilter</filter-name>
43     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
44     <init-param>
45       <param-name>encoding</param-name>
46       <param-value>UTF-8</param-value>
47     </init-param>
48     <init-param>
49       <param-name>forceEncoding</param-name>
50       <param-value>true</param-value>
51     </init-param>
52   </filter>
53   <filter-mapping>
54     <filter-name>characterEncodingFilter</filter-name>
55     <url-pattern>/*</url-pattern>
56   </filter-mapping>
57   
58 </web-app>
2,6). Entity class Users object
 1 package com.svse.entity;
 2 import java.io.Serializable;
 3 
 4 public class Users implements Serializable{
 5 
 6     private String userId;
 7     private String userName;
 8     private String sex;
 9     private String age;
10     private String type;
11     
12     
13     public Users() {
14         super();
15     }
16     public Users(String userId, String userName, String sex, String age,
17             String type) {
18         super();
19         this.userId = userId;
20         this.userName = userName;
21         this.sex = sex;
22         this.age = age;
23         this.type = type;
24     }
25     public String getUserId() {
26         return userId;
27     }
28     public void setUserId(String userId) {
29         this.userId = userId;
30     }
31     public String getUserName() {
32         return userName;
33     }
34     public void setUserName(String userName) {
35         this.userName = userName;
36     }
37     public String getSex() {
38         return sex;
39     }
40     public void setSex(String sex) {
41         this.sex = sex;
42     }
43     public String getAge() {
44         return age;
45     }
46     public void setAge(String age) {
47         this.age = age;
48     }
49     public String getType() {
50         return type;
51     }
52     public void setType(String type) {
53         this.type = type;
54     }
55     @Override
56     public String toString() {
57         return "Users [userId=" + userId + ", userName=" + userName + ", sex="
58                 + sex + ", age=" + age + ", type=" + type + "]";
59     }
60     
61     
62 }
2,7). Core code (ProducerService)
 1 package com.svse.service;
 2 
 3 import javax.annotation.Resource;
 4 import javax.jms.Destination;
 5 import javax.jms.JMSException;
 6 import javax.jms.Message;
 7 import javax.jms.Session;
 8 
 9 import org.springframework.jms.core.JmsTemplate;
10 import org.springframework.jms.core.MessageCreator;
11 import org.springframework.stereotype.Service;
12 
13 import com.svse.entity.Users;
14 
15 @Service
16 public class ProducerService {
17 
18     @Resource(name="jmsTemplate")
19     private JmsTemplate jmsTemplate;
20     
21     
22     /**
23      * 向指定队列发送消息 (发送文本消息)
24      */
25     public void sendMessage(Destination destination,final String msg){
26         
27         jmsTemplate.setDeliveryPersistent(true);
28         
29         System.out.println(Thread.currentThread().getName()+" 向队列"+destination.toString()+"发送消息---------------------->"+msg);
30         jmsTemplate.send(destination, new MessageCreator() {
31             public Message createMessage(Session session) throws JMSException {
32                 return session.createTextMessage(msg);
33             }
34         });
35     }
36     
37     /**
38      * 向指定队列发送消息以对象的方式 (发送对象消息)
39      */
40     public void sendMessageNew(Destination destination,Users user){
41         System.out.println(Thread.currentThread().getName()+" 向队列"+destination.toString()+"发送消息---------------------->"+user);
42         jmsTemplate.convertAndSend(user);
43     }
44 
45     /**
46      * 向默认队列发送消息
47      */
48     public void sendMessage(final String msg){
49         String destination = jmsTemplate.getDefaultDestinationName();
50         System.out.println(Thread.currentThread().getName()+" 向队列"+destination+"发送消息---------------------->"+msg);
51         jmsTemplate.send(new MessageCreator() {
52             public Message createMessage(Session session) throws JMSException {
53                 return session.createTextMessage(msg);
54             }
55         });
56     }
57 }
2,8). Core code (ConsumerService)
 1 package com.svse.service;
 2 
 3 import javax.annotation.Resource;
 4 import javax.jms.Destination;
 5 import javax.jms.JMSException;
 6 import javax.jms.ObjectMessage;
 7 import javax.jms.TextMessage;
 8 
 9 import net.sf.json.JSONObject;
10 
11 import org.springframework.jms.core.JmsTemplate;
12 import org.springframework.stereotype.Service;
13 
14 import com.svse.entity.Users;
15 
16 @Service
17 public class ConsumerService {
18 
19      @Resource(name="jmsTemplate")
20      private JmsTemplate jmsTemplate;
21      //接收文本消息
22      public TextMessage receive(Destination destination){
23             TextMessage textMessage = (TextMessage) jmsTemplate.receive(destination);
24             try{
25                 JSONObject json=JSONObject.fromObject(textMessage.getText());
26                 System.out.println("name:"+json.getString("userName"));
27                 System.out.println("从队列" + destination.toString() + "收到了消息:\t"
28                         + textMessage.getText());
29             } catch (JMSException e) {
30                 e.printStackTrace();
31             }
32             return textMessage;
33         }
34      //接收对象消息
35      public ObjectMessage receiveNew(Destination destination){
36              ObjectMessage objMsg=(ObjectMessage) jmsTemplate.receive(destination);
38              try{
39                 Users users= (Users) objMsg.getObject();
44                 System.out.println("name:"+users.getUserName());
47                 System.out.println("从队列" + destination.toString() + "收到了消息:\t"
48                         + users);
49             } catch (JMSException e) {
50                 e.printStackTrace();
51             }
52             return objMsg;
53         }
54 }
2,9). Core code (controller ConsumerService)
  1 package com.svse.controller.mq;
  2 
  3 import java.io.IOException;
  4 import java.text.SimpleDateFormat;
  5 import java.util.Date;
  7 import javax.annotation.Resource;
  8 import javax.jms.DeliveryMode;
  9 import javax.jms.Destination;
 10 import javax.jms.JMSException;
 11 import javax.jms.ObjectMessage;
 12 import javax.jms.TextMessage;
 13 import javax.management.MBeanServerConnection;
 14 import javax.management.remote.JMXConnector;
 15 import javax.management.remote.JMXConnectorFactory;
 16 import javax.management.remote.JMXServiceURL;
 18 import org.springframework.stereotype.Controller;
 19 import org.springframework.web.bind.annotation.RequestMapping;
 20 import org.springframework.web.bind.annotation.RequestMethod;
 21 import org.springframework.web.bind.annotation.RequestParam;
 22 import org.springframework.web.servlet.ModelAndView;
 24 import com.google.gson.Gson;
 25 import com.svse.entity.Users;
 26 import com.svse.service.ConsumerService;
 27 import com.svse.service.ProducerService;
 28 
 29 @Controller
 30 public class DemoController {
 35     
 36      //队列名Jaycekon (ActiveMQ中设置的队列的名称)
 37     @Resource(name="demoQueueDestination")
 38     private Destination demoQueueDestination;
 39 
 40     //队列消息生产者
 41     @Resource(name="producerService")
 42     private ProducerService producer;
 43     
 44    //队列消息消费者
 45     @Resource(name="consumerService")
 46     private ConsumerService consumer;
 47     
 48     /*
 49      * 准备发消息
 50      */
 51     @RequestMapping(value="/producer",method=RequestMethod.GET)
 52     public ModelAndView producer(){
 53         System.out.println("------------go producer");
 54         
 55         Date now = new Date(); 
 56         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 57         String time = dateFormat.format( now ); 
 58         System.out.println(time);
 59         
 60         ModelAndView mv = new ModelAndView();
 61         mv.addObject("time", time);
 62         mv.setViewName("producer");        
 63         return mv;
 64     }
 65     
 66     /*
 67      * 发消息
 68      */
 69     @RequestMapping(value="/onsend",method=RequestMethod.POST)
 70     public ModelAndView producer(@RequestParam("message") String message) {
 71         System.out.println("------------send to jms");
 72         ModelAndView mv = new ModelAndView();
 73         for(int i=0;i<5;i++){
 74             try {
 75                 Users users=new Users("10"+(i+1),"赵媛媛"+(i+1),"女","27","影视演员");
 76                 Gson gson=new Gson();
 77                 String sendMessage=gson.toJson(users);
 78                 System.out.println("发送的消息sendMessage:"+sendMessage.toString());
 79              // producer.sendMessage(demoQueueDestination,sendMessage.toString());//以文本的形式
 80               producer.sendMessageNew(demoQueueDestination, users);//以对象的方式
 81              
 82             } catch (Exception e) {
 83                 e.printStackTrace();
 84             }
 85         }
 86         mv.setViewName("index");
 87         return mv;
 88     }
 89     /*
 90      * 手动接收消息
 91      */
 92     @RequestMapping(value="/receive",method=RequestMethod.GET)
 93     public ModelAndView queue_receive() throws JMSException {
 94         System.out.println("------------receive message");
 95         ModelAndView mv = new ModelAndView();
 96         
 97       //TextMessage tm = consumer.receive(demoQueueDestination);//接收文本消息
 98         
 99         ObjectMessage objMsg=consumer.receiveNew(demoQueueDestination);//接收对象消息
100         Users users= (Users) objMsg.getObject();
101         //mv.addObject("textMessage", tm.getText());
102         mv.addObject("textMessage", users.getUserId()+" || "+users.getUserName());
103         mv.setViewName("receive");
104         return mv;
105     }
106     
107     /*
108      * ActiveMQ Manager Test
109      */
110     @RequestMapping(value="/jms",method=RequestMethod.GET)
111     public ModelAndView jmsManager() throws IOException {
112         System.out.println("------------jms manager");
113         ModelAndView mv = new ModelAndView();
114         mv.setViewName("index");
115         
116         JMXServiceURL url = new JMXServiceURL("");
117         JMXConnector connector = JMXConnectorFactory.connect(url);
118         connector.connect();
119         MBeanServerConnection connection = connector.getMBeanServerConnection();
120         
121         return mv;
122     }
123     
124 }

3. Object converter MessageConverter and message listener MessageListener

In the above ProducerService and ConsumerService, whether you are sending or receiving messages, you can use TextMessage and ObjectMessage. If it is a simple text message, you can use TextMessage, but if you need to send more content, the structure is more complex , At this time, it is recommended to use the object text ObjectMessage to send messages to the queue queue. But at this time, you need to use the object message converter MessageConverter.

3,1). Message converter MessageageConverte

MessageConverter has two main functions. On the one hand, it can convert our non-standardized Message object into our target Message object, which is mainly used when sending messages; on the other hand, it can convert our Message object into The corresponding target object, which is mainly used when receiving messages.

 1 package com.svse.util;
 2 
 3 import java.io.Serializable;
 4 
 5 import javax.jms.JMSException;
 6 import javax.jms.Message;
 7 import javax.jms.ObjectMessage;
 8 import javax.jms.Session;
 9 
10 import org.springframework.jms.support.converter.MessageConversionException;
11 import org.springframework.jms.support.converter.MessageConverter;
12 
13 /**
14  *功能说明:通用的消息对象转换类
15  *@author:zsq
16  *create date:2019年7月12日 上午9:28:31
17  *修改人   修改时间  修改描述
18  *Copyright (c)2019北京智华天成科技有限公司-版权所有
19  */
20 public class ObjectMessageConverter implements MessageConverter {
21 
22     
23     //把一个Java对象转换成对应的JMS Message (生产消息的时候)
24     public Message toMessage(Object object, Session session)
25             throws JMSException, MessageConversionException {
26         
27         return session.createObjectMessage((Serializable) object);  
28     }
29 
30     //把一个JMS Message转换成对应的Java对象 (消费消息的时候)
31     public Object fromMessage(Message message) throws JMSException,
32             MessageConversionException {
33         ObjectMessage objMessage = (ObjectMessage) message;  
34         return objMessage.getObject();  
35     }
36 
37 }

Note: After writing the message converter, you need to configure it in ActiveMQ.xml

3,2). Message listener MessageageListe

The role of MessageageListe is to dynamically monitor the messages sent by the producers of the message queue, without the need for manual reception!

 1 package com.svse.util;
 2 import javax.jms.JMSException;
 3 import javax.jms.Message;
 4 import javax.jms.MessageListener;
 5 import javax.jms.ObjectMessage;
 6 import javax.jms.TextMessage;
 7 
 8 import com.svse.entity.Users;
 9 
10 
11 public class QueueMessageListener implements MessageListener {
12 
13    //添加了监听器,只要生产者发布了消息,监听器监听到有消息消费者就会自动消费(获取消息)
14     public void onMessage(Message message) {
15          //(第1种方式)没加转换器之前接收到的是文本消息
16         //TextMessage tm = (TextMessage) message;
17         
18         //(第2种方式)加了转换器之后接收到的ObjectMessage对象消息
19         ObjectMessage objMsg=(ObjectMessage) message;
20          Users users;
21         try {
22             users = (Users) objMsg.getObject();
23             //System.out.println("QueueMessageListener监听到了文本消息:\t" + tm.getText());
24             System.out.println("QueueMessageListener监听到了文本消息:\t" + users);      
25             //do something ...
26         } catch (JMSException e1) {
27             // TODO Auto-generated catch block
28             e1.printStackTrace();
29         }
30     }
31     
32 }

After writing the listener, it also needs to be configured and registered in ActiveMQ.xml

Summarize

(1) When registering JmsTemplate, pay special attention to the value of the pubSubDomain attribute. The default value is false, which means that only queue mode is supported by default, and topic mode is not supported. However, if you change it to true, queue mode is not supported. Therefore, if the project needs to support both queue and topic modes, it needs to register 2 JmsTemplates, and the listener container also needs to register 2

(2) When using Queue, as long as the producer sends the Message to the MQ server, the consumer can consume without the need for the producer program to run all the time;

(3) Messages are in first-in, first-out order. Once a consumer consumes a Message, the Message will be deleted from the MQ server queue;

(4) Some articles say that "producer" <--> "consumer" is a one-to-one relationship, which is not accurate. It can be seen from the application that a message generated by a producer can be consumed by multiple consumers. The message is consumed by multiple consumers, but multiple consumers are in a competitive relationship when consuming messages. The one that gets first consumes first. Once the consumption is completed, the message will be dequeued and cannot be consumed by other consumers again, that is, "one-time" Consumption". It is the "point-to-point" communication that we are familiar with;

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324127556&siteId=291194637