作者:一一哥
我在上一章节中,给大家介绍了ActiveMQ,本节中我会介绍Spring Boot中如何整合ActiveMQ,实现消息的创建和消费。
我们按照之前的经验,创建一个web程序,并将之改造成Spring Boot项目,具体过程略。

org.springframework.boot
spring-boot-starter-activemq
#配置activemq
spring:
activemq:
#activemq的url
broker-url: tcp://127.0.0.1:61616
#用户名
user: admin
#密码
password: admin
pool:
enabled: false #是否使用线程池
max-connections: 100 #最大连接数
#是否信任所有包
packages:
trust-all: true
#默认情况下,activemq使用的是queue模式,如果要使用topic模式,必须设置为true
jms:
pub-sub-domain: true
在这个类中创建连接工厂,消息队列等。
package com.yyg.boot.config;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Topic;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/14
* @Description Description
* //@EnableJms启用jms功能
*/
@Configuration
@EnableJms
public class ActivemqConfig {
@Autowired
private Environment env;
@Bean
public ConnectionFactory connectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(env.getProperty("spring.activemq.broker-url"));
connectionFactory.setUserName(env.getProperty("spring.activemq.user"));
connectionFactory.setPassword(env.getProperty("spring.activemq.password"));
return connectionFactory;
}
/**
* 实现监听queue
*/
@Bean("jmsQueueListenerContainerFactory")
public JmsListenerContainerFactory> queueContainerFactory(ConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//开启接收topic类型的消息
factory.setPubSubDomain(false);
return factory;
}
/**
* 实现监听topic
*/
@Bean("jmsTopicListenerContainerFactory")
public JmsListenerContainerFactory> topicContainerFactory(ConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(true);
return factory;
}
/**
* 队列名称
*/
@Bean("springboot.queue")
public Queue queue() {
return new ActiveMQQueue("springboot.queue") ;
}
/**
* Topic名称
*/
@Bean("springboot.topic")
public Topic topic() {
return new ActiveMQTopic("springboot.topic") ;
}
}
在这个Producer类中,创建几个发送消息的的方法。
package com.yyg.boot.jms;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.Queue;
import javax.jms.Topic;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/15
* @Description 消息生产者
*/
@Slf4j
@Component
public class Producer {
@Resource(name = "springboot.queue")
private Queue queue;
@Resource(name = "springboot.topic")
private Topic topic;
@Resource(name = "springboot.replyQueue")
private Queue replyQueue;
@Autowired
private JmsMessagingTemplate jmsTemplate;
/**
* 发送消息,destination是发送到的目标队列,message是待发送的消息内容;
*/
public void sendMessage(Destination destination, final String message) {
jmsTemplate.convertAndSend(destination, message);
}
/**
* 发送队列消息
*/
public void sendQueueMessage(final String message) {
sendMessage(queue, message);
}
/**
* 发送Topic消息
*/
public void sendTopicMessage(final String message) {
sendMessage(topic, message);
}
}
package com.yyg.boot.jms;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/15
* @Description 消息的消费者
*/
@Slf4j
@Component
public class Consumer {
/**
* 监听Queue队列,queue类型
*/
@JmsListener(destination="springboot.queue",
containerFactory = "jmsQueueListenerContainerFactory")
public void receiveQueue(String text){
log.warn(this.getClass().getName()+ "-->收到的报文为:"+text);
}
/**
* 监听Topic队列,topic类型,这里containerFactory要配置为jmsTopicListenerContainerFactory
*/
@JmsListener(destination = "springboot.topic",
containerFactory = "jmsTopicListenerContainerFactory")
public void receiveTopic(String text) {
log.warn(this.getClass().getName()+"-->收到的报文为:"+text);
}
}
package com.yyg.boot.web;
import com.yyg.boot.domain.User;
import com.yyg.boot.jms.Consumer;
import com.yyg.boot.jms.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/15
* @Description Description
*/
@RestController
public class MsgController {
@Autowired
private Producer producer;
@Autowired
private Consumer consumer;
@GetMapping("/sendQueue")
public String sendQueueMsg() {
User user = new User();
user.setId(1L);
user.setUsername("一一哥Queue");
user.setPassword("123");
producer.sendQueueMessage(user.toString());
return "发送成功!";
}
@GetMapping("/sendTopic")
public String sendTopicMsg() {
User user = new User();
user.setId(2L);
user.setUsername("一一哥Topic");
user.setPassword("123456");
producer.sendTopicMessage(user.toString());
return "发送成功!";
}
}
package com.yyg.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ActiveMQApplication {
public static void main(String[] args) {
SpringApplication.run(ActiveMQApplication.class, args);
}
}

队列中可以看到成功的收到了消息。

在ActiveMQ中也可以看到出现了springboot.queue队列,并且队列中的消息已被消费掉。

在ActiveMQ中也可以看到出现了springboot.topic队列,并且队列中的消息已被消费掉。

我们在上面的基础之上,进一步实现发送消息后,进行消息的回复。
在该类中添加一个用来接收回复消息的队列。
/**
* 回复队列名称
*/
@Bean("springboot.replyQueue")
public Queue queueReply() {
return new ActiveMQQueue("springboot.replyQueue") ;
}
完整的ActivemqConfig代码:
package com.yyg.boot.config;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Topic;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/14
* @Description Description
* //@EnableJms启用jms功能
*/
@Configuration
@EnableJms
public class ActivemqConfig {
@Autowired
private Environment env;
@Bean
public ConnectionFactory connectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(env.getProperty("spring.activemq.broker-url"));
connectionFactory.setUserName(env.getProperty("spring.activemq.user"));
connectionFactory.setPassword(env.getProperty("spring.activemq.password"));
return connectionFactory;
}
/**
* 实现监听queue
*/
@Bean("jmsQueueListenerContainerFactory")
public JmsListenerContainerFactory> queueContainerFactory(ConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//开启接收topic类型的消息
factory.setPubSubDomain(false);
return factory;
}
/**
* 实现监听topic
*/
@Bean("jmsTopicListenerContainerFactory")
public JmsListenerContainerFactory> topicContainerFactory(ConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(true);
return factory;
}
/**
* 队列名称
*/
@Bean("springboot.queue")
public Queue queue() {
return new ActiveMQQueue("springboot.queue") ;
}
/**
* Topic名称
*/
@Bean("springboot.topic")
public Topic topic() {
return new ActiveMQTopic("springboot.topic") ;
}
/**
* 回复队列名称
*/
@Bean("springboot.replyQueue")
public Queue queueReply() {
return new ActiveMQQueue("springboot.replyQueue") ;
}
}
在Producer类中定义一个新的Queue类,并定义发送消息和消费消息的方法。
@Resource(name = "springboot.replyQueue")
private Queue replyQueue;
/**
* 发送队列的回复消息
*/
public void sendQueueMessageReply(String message) {
sendMessage(replyQueue, message);
}
/**
* 生产者监听消费者的应答信息
*/
@JmsListener(destination = "replyTo.queue",containerFactory = "jmsQueueListenerContainerFactory")
public void consumerMessage(final String text) {
log.warn("从replyTo.queue队列中收到的应答报文为:" + text);
}
完整的Producer类代码:
package com.yyg.boot.jms;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.Queue;
import javax.jms.Topic;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/15
* @Description 消息生产者
*/
@Slf4j
@Component
public class Producer {
@Resource(name = "springboot.queue")
private Queue queue;
@Resource(name = "springboot.topic")
private Topic topic;
@Resource(name = "springboot.replyQueue")
private Queue replyQueue;
@Autowired
private JmsMessagingTemplate jmsTemplate;
/**
* 发送消息,destination是发送到的目标队列,message是待发送的消息内容;
*/
public void sendMessage(Destination destination, final String message) {
jmsTemplate.convertAndSend(destination, message);
}
/**
* 发送队列消息
*/
public void sendQueueMessage(final String message) {
sendMessage(queue, message);
}
/**
* 发送Topic消息
*/
public void sendTopicMessage(final String message) {
sendMessage(topic, message);
}
/**
* 发送队列的回复消息
*/
public void sendQueueMessageReply(String message) {
sendMessage(replyQueue, message);
}
/**
* 生产者监听消费者的应答信息
*/
@JmsListener(destination = "replyTo.queue",containerFactory = "jmsQueueListenerContainerFactory")
public void consumerMessage(final String text) {
log.warn("从replyTo.queue队列中收到的应答报文为:" + text);
}
}
在该类中添加接收消息,并且设置回复消息的方法。
/**
* 回复给生产者的应答信息
*/
@JmsListener(destination="springboot.replyQueue",containerFactory = "jmsQueueListenerContainerFactory")
@SendTo("replyTo.queue") //消费者应答后通知生产者
public String receiveQueueReply(String text){
log.warn(this.getClass().getName()+ "-->收到的报文为:"+text);
return "回复的信息为-->"+text;
}
完整的Consumer类代码:
package com.yyg.boot.jms;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;
/**
* @Author 一一哥Sun
* @Date Created in 2020/4/15
* @Description 消息的消费者
*/
@Slf4j
@Component
public class Consumer {
/**
* 监听Queue队列,queue类型
*/
@JmsListener(destination="springboot.queue",
containerFactory = "jmsQueueListenerContainerFactory")
public void receiveQueue(String text){
log.warn(this.getClass().getName()+ "-->收到的报文为:"+text);
}
/**
* 监听Topic队列,topic类型,这里containerFactory要配置为jmsTopicListenerContainerFactory
*/
@JmsListener(destination = "springboot.topic",
containerFactory = "jmsTopicListenerContainerFactory")
public void receiveTopic(String text) {
log.warn(this.getClass().getName()+"-->收到的报文为:"+text);
}
/**
* 回复给生产者的应答信息
*/
@JmsListener(destination="springboot.replyQueue",containerFactory = "jmsQueueListenerContainerFactory")
@SendTo("replyTo.queue") //消费者应答后通知生产者
public String receiveQueueReply(String text){
log.warn(this.getClass().getName()+ "-->收到的报文为:"+text);
return "回复的信息为-->"+text;
}
}
至此,我们实现了Spring boot中如何整合ActiveMQ。