使用artemis版本MQ。Spring JMS 使用springframework-mvc架构,传统xml配置,部署到tomcat运行。如果采用springboot将更简单。有空将更新成springboot
注: ActiveMQ下载的artemis版本,与之前的ActiveMQ版本有点区别,
下载地址 https://activemq.apache.org/index.html
./artemis create /Users/somnus/Documents/software/myInstance
# ./artemis create /Users/somnus/Documents/software/myInstance
cd ./artemis create /Users/somnus/Documents/software/myInstance/bin
./artemis run #运行activemq
5.通过浏览器访问activemq控制台
地址 http://localhost:8161/
6. 进入控制台Management Console
路径:http://localhost:8161/console/login,记不住,直接http://localhost:8161通过点击进入
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.10.3version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>4.0.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.apache.activemqgroupId>
<artifactId>artemis-jms-clientartifactId>
<version>2.11.0version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jmsartifactId>
<version>5.2.4.RELEASEversion>
dependency>
dependencies>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>appservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>appservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
web-app>
配置文件名:app-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<mvc:component-scan base-package="com.teachayu.activemq" />
<bean id="connectionFactory" class="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory" />
<bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="connectionFactory"/>
bean>
<bean id="messageConverter" class="org.springframework.jms.support.converter.MappingJackson2MessageConverter" >
<property name="typeIdPropertyName" value="test" />
<property name="typeIdMappings" >
<map>
<entry key="test" value="com.teachayu.activemq.controller.UserEntity"/>
map>
property>
bean>
<bean id="pointJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
<constructor-arg ref="connectionFactory">constructor-arg>
<property name="defaultDestinationName" value="test"/>
<property name="messageConverter" ref="messageConverter"/>
<property name="pubSubDomain" value="false" />
bean>
<bean id="receiveListener" class="com.teachayu.activemq.controller.TextReceiveListener">bean>
<bean id="defaultMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="messageListener" ref="receiveListener"/>
<property name="messageConverter" ref="messageConverter"/>
<property name="destinationName" value="test"/>
<property name="connectionFactory" ref="connectionFactory"/>
bean>
<bean id="pojoMessageConverter" class="com.teachayu.activemq.controller.PojoMessageConverter"/>
<bean id="pojoJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
<constructor-arg ref="connectionFactory">constructor-arg>
<property name="defaultDestinationName" value="test"/>
<property name="messageConverter" ref="pojoMessageConverter"/>
<property name="pubSubDomain" value="false" />
bean>
<bean class="com.teachayu.activemq.controller.Pojo1ReceiveListener" id="pojo1ReceiveListener"/>
<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer" >
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destinationName" value="pojo1"/>
<property name="messageConverter" ref="pojoMessageConverter"/>
<property name="messageListener" ref="pojo1ReceiveListener"/>
bean>
<bean id="pubJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
<property name="connectionFactory" ref="cachingConnectionFactory"/>
<property name="defaultDestinationName" value="pub"/>
<property name="messageConverter" ref="pojoMessageConverter"/>
<property name="pubSubDomain" value="true" />
bean>
<bean class="com.teachayu.activemq.controller.Subscribe1Listener" id="subscribe1Listener"/>
<bean class="com.teachayu.activemq.controller.Subscribe2Listener" id="subscribe2Listener"/>
<bean id="listenerContainer1" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="pubSubDomain" value="true"/>
<property name="destinationName" value="pub"/>
<property name="messageListener" ref="subscribe1Listener"/>
<property name="messageConverter" ref="pojoMessageConverter"/>
<property name="connectionFactory" ref="cachingConnectionFactory"/>
bean>
<bean id="listenerContainer2" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="pubSubDomain" value="true"/>
<property name="messageListener" ref="subscribe2Listener"/>
<property name="messageConverter" ref="pojoMessageConverter"/>
<property name="destinationName" value="pub"/>
<property name="connectionFactory" ref="cachingConnectionFactory"/>
bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list><value>text/html;charset=UTF-8value>
<value>application/json;charset=UTF-8value>
list>
property>
bean>
list>
property>
bean>
beans>
定义PojoMessageConverter消息转换器,将Object转成ObjectMessage消息,或将ObjectMessage消息转成Object。Object将实现Serializable接口
package com.teachayu.activemq.controller;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import java.io.Serializable;
public class PojoMessageConverter implements MessageConverter {
@Override
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
return session.createObjectMessage((Serializable) object);
}
@Override
public Object fromMessage(Message message) throws JMSException, MessageConversionException {
return ((ObjectMessage)message).getObject();
}
}
实体类,用于测试
package com.teachayu.activemq.controller;
import java.io.Serializable;
public class UserEntity implements Serializable {
private String name;
private int age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "UserEntity{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
发送消息与发布消息,通过http://localhost:8080/activemq/send 完成简单消息推送
package com.teachayu.activemq.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
/**
* 使用Point-to-Point模式发送消息
* 使用Publish/Subscribe 模式发布消息
*/
@RestController
public class ProducerController {
/**
* 发送文本消息模板 Point-to-Point
* MappingJackson2MessageConverter转换器
*/
private JmsTemplate jmsTemplate;
/**
* 发送对象消息 Point-to-Point
* PojoMessageConverterz转换器
*/
private JmsTemplate pojoJmsTemplate;
/**
* 发布对象消息 Publish/Subscribe
* PojoMessageConverterz转换器
*/
private JmsTemplate pubJmsTemplate;
@RequestMapping("/send")
public String send(){
/**
* Point-to-Point 模式
* 使用默认队列发送消息
* 使用JmsTemplate同步接收
*/
jmsTemplate.send(new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
//发送TextMessage消息
return session.createTextMessage("text队列发送消息(接收同步):"+System.currentTimeMillis());
}
});
/**
* Point-to-Point 模式
* 使用默认队列发送消息
* 异步接收 MessageListener
*/
jmsTemplate.send("text1", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
//发送TextMessage消息
return session.createTextMessage("text1队列发送消息(接收异步)"+System.currentTimeMillis());
}
});
/**
* Point-to-Point 模式
* 使用定义的转换器
* org.springframework.jms.support.converter.MappingJackson2MessageConverter
* 使用pojo队列发送消息
* 使用JmsTemplate同步接收
*/
UserEntity userEntity = new UserEntity();
long l = System.currentTimeMillis();
userEntity.setName("张三"+l);
userEntity.setAddress("地址"+l);
userEntity.setAge(1);
jmsTemplate.convertAndSend("pojo",userEntity);
/**
* Point-to-Point 模式
* 使用定义的转换器 com.teachayu.activemq.controller.PojoMessageConverter
* 使用pojo队列发送消息
* 异步接收 MessageListener
*/
userEntity = new UserEntity();
l = System.currentTimeMillis();
userEntity.setName("张三"+l);
userEntity.setAddress("地址"+l);
userEntity.setAge(1);
pojoJmsTemplate.convertAndSend("pojo1",userEntity);
/**
* Publish/Subscribe 模式
* 发布消息
* 默认队列 pub ,配置文件中
*/
userEntity = new UserEntity();
l = System.currentTimeMillis();
userEntity.setName("张三"+l);
userEntity.setAddress("地址"+l);
userEntity.setAge(1);
pubJmsTemplate.convertAndSend("pub",userEntity);
return "hello";
}
@Autowired
@Qualifier("pointJmsTemplate")
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
@Autowired
@Qualifier("pojoJmsTemplate")
public void setPojoJmsTemplate(JmsTemplate pojoJmsTemplate) {
this.pojoJmsTemplate = pojoJmsTemplate;
}
@Autowired
@Qualifier("pubJmsTemplate")
public void setPubJmsTemplate(JmsTemplate pubJmsTemplate) {
this.pubJmsTemplate = pubJmsTemplate;
}
}
同步接收消息,是阻塞模式,通过http://localhost:8080/activemq/receive接收消息。
注意:一定要先执行send请求,完成消费发送,不是receive请求将阻塞
package com.teachayu.activemq.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.jms.JMSException;
import javax.jms.TextMessage;
/**
* 阻塞模式接收消息
*/
@RestController
public class CustomerController {
private JmsTemplate jmsTemplate;
@RequestMapping("receive")
public UserEntity receive() throws JMSException {
//阻塞接收消息,默认队列,队列中无消息将阻塞
TextMessage message = (TextMessage)jmsTemplate.receive();
System.out.println("接收test队列:"+message.getText());
//阻塞接收消息,pojo队列,队列中无消息将阻塞
UserEntity userEntity = (UserEntity)jmsTemplate.receiveAndConvert("pojo");
System.out.println("接收pojo队列消息"+ userEntity);
return userEntity;
}
@Autowired
@Qualifier("pointJmsTemplate")
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
}
采用监听模式接收消息,有消息来将自动获取消息
package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
* 监听接收消息
*/
public class TextReceiveListener implements MessageListener {
@Override
public void onMessage(Message message) {
try {
String text = ((TextMessage) message).getText();
System.out.println("接收到test队列消息:"+text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
/**
* 队列监听器 pojo1队列
* PojoMessageConverter完成转换
*/
public class Pojo1ReceiveListener implements MessageListener {
@Override
public void onMessage(Message message) {
try {
UserEntity userEntity = (UserEntity) ((ObjectMessage) message).getObject();
System.out.println("接收pojo1队列消息:"+ message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Subscribe1Listener 订阅pub主题消息
package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
/**
* 订阅消息
*/
public class Subscribe1Listener implements MessageListener {
@Override
public void onMessage(Message message) {
UserEntity userEntity = null;
try {
userEntity = (UserEntity) ((ObjectMessage) message).getObject();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("Subscribe1Listener订阅pub队列消息:" + userEntity);
}
}
Subscribe2Listener 订阅pub主题消息
package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
/**
* 订阅消息
*/
public class Subscribe2Listener implements MessageListener {
@Override
public void onMessage(Message message) {
UserEntity userEntity = null;
try {
userEntity = (UserEntity) ((ObjectMessage) message).getObject();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("Subscribe2Listener订阅pub队列消息:" + userEntity);
}
}
前提是运行activemq与springJMS项目,将可以进行以下测试。测试就不截图了。
通过浏览器访问 http://localhost:8080/activemq/send 将完成所有消息发送。
https://docs.spring.io/spring/docs/5.2.5.RELEASE/spring-framework-reference/integration.html#remoting-jms
http://localhost:8161/user-manual/index.html #该地址是安装activemq之后访问可以看到。
或者通过以下官网地址查看文档
https://activemq.apache.org/components/artemis/documentation/