一、Windows安装 ActiveMq
- 下载地址:http://activemq.apache.org/download-archives.html,这里使用的是压缩版
apache-activemq-5.15.14-bin.zip
- 将下载的压缩包解压,CMD进入解压目录的bin目录下,执行 activemq.bat start 启动
- 若能访问 http://localhost:8161,则说明启动成功
二、创建一个SpringBoot项目
springBoot基础环境搭建这里不做赘述,不清楚的可参考:baidu
1. 引入activemq依赖
<!-- activemq 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
<!-- 若用到连接池 引入以下依赖 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.0</version>
</dependency>
2. application.yml文件配置
添加以下配置:
spring:
activemq:
user: admin
password: admin
broker-url: tcp://192.168.1.244:61616
close-timeout: 15s # 在考虑结束之前等待的时间
in-memory: true # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
non-blocking-redelivery: false # 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留。
#send-timeout: 0 # 等待消息发送响应的时间。设置为0等待永远。
queue-name: active.queue
topic-name: active.topic.name.model
# 连接池
pool:
enabled: false
max-connections: 10 #连接池最大连接数
#idle-timeout: 30000 #空闲的连接过期时间,默认为30秒
扩展配置:
# 默认情况下activemq提供的是queue模式,若要使用topic模式需要配置下面配置
# spring.jms.pub-sub-domain=true
# 是否信任所有包
# spring.activemq.packages.trust-all=
# 要信任的特定包的逗号分隔列表(当不信任所有包时)
# spring.activemq.packages.trusted=
# 当连接请求和池满时是否阻塞。设置false会抛“JMSException异常”。
# spring.activemq.pool.block-if-full=true
# 如果池仍然满,则在抛出异常前阻塞时间。
# spring.activemq.pool.block-if-full-timeout=-1ms
# 是否在启动时创建连接。可以在启动时用于加热池。
# spring.activemq.pool.create-connection-on-startup=true
# 是否用Pooledconnectionfactory代替普通的ConnectionFactory。
# spring.activemq.pool.enabled=false
# 连接过期超时。
# spring.activemq.pool.expiry-timeout=0ms
# 连接空闲超时
# spring.activemq.pool.idle-timeout=30s
# 连接池最大连接数
# spring.activemq.pool.max-connections=1
# 每个连接的有效会话的最大数目。
# spring.activemq.pool.maximum-active-session-per-connection=500
# 当有"JMSException"时尝试重新连接
# spring.activemq.pool.reconnect-on-exception=true
# 在空闲连接清除线程之间运行的时间。当为负数时,没有空闲连接驱逐线程运行。
# spring.activemq.pool.time-between-expiration-check=-1ms
# 是否只使用一个MessageProducer
# spring.activemq.pool.use-anonymous-producers=true
3. 启动类增加 @EnableJms
注解
4. 初始化ActiveMQ配置
@Configuration
public class ActiveMQConfig {
@Value("${spring.activemq.broker-url}")
private String brokerUrl;
@Value("${spring.activemq.user}")
private String username;
@Value("${spring.activemq.topic-name}")
private String password;
@Value("${spring.activemq.queue-name}")
private String queueName;
@Value("${spring.activemq.topic-name}")
private String topicName;
@Bean(name = "queue")
public Queue queue() {
return new ActiveMQQueue(queueName);
}
// 自定义队列
@Bean(name = "queue1")
public Queue queue1() {
return new ActiveMQQueue("queue1");
}
@Bean(name = "topic")
public Topic topic() {
return new ActiveMQTopic(topicName);
}
// 自定义队列
@Bean(name = "topic1")
public Topic topic1() {
return new ActiveMQTopic("topic1");
}
@Bean
public ConnectionFactory connectionFactory(){
return new ActiveMQConnectionFactory(username, password, brokerUrl);
}
@Bean
public JmsMessagingTemplate jmsMessageTemplate(){
return new JmsMessagingTemplate(connectionFactory());
}
// 在Queue模式中,对消息的监听需要对containerFactory进行配置
@Bean("queueListener")
public JmsListenerContainerFactory<?> queueJmsListenerContainerFactory(ConnectionFactory connectionFactory){
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(false);
return factory;
}
//在Topic模式中,对消息的监听需要对containerFactory进行配置
@Bean("topicListener")
public JmsListenerContainerFactory<?> topicJmsListenerContainerFactory(ConnectionFactory connectionFactory){
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(true);
return factory;
}
}
5. 生产者
@RestController
@RequestMapping("/publish")
public class PublishController {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Queue queue;
@Autowired
private Queue queue1; // 自定义队列 可以多个 互不干扰
@Autowired
private Topic topic;
@Autowired
private Topic topic1;
@RequestMapping("/queue/test")
public String queue(String name){
for (int i = 0; i < 10 ; i++){
jmsMessagingTemplate.convertAndSend(queue, "队列queue-"+i);
jmsMessagingTemplate.convertAndSend(queue1, AjaxResult.success("队列queue1-" + i));
}
return name + "-queue- 发送成功";
}
@JmsListener(destination = "out.queue")
public void consumerMsg(String msg){
System.out.println(">>>>>>" + msg);
}
@RequestMapping("/topic/test")
public String topic(){
for (int i = 0; i < 10 ; i++){
jmsMessagingTemplate.convertAndSend(topic, "topic-"+i);
jmsMessagingTemplate.convertAndSend(topic1, "topic-1-"+i);
}
return "topic 发送成功";
}
}
注意,代码中的AjaxResult
是自己封装的实体,目的是为了测试传输的数据类型
6. 消费者
@Component
public class QueueConsumerListener {
//queue模式的消费者
/** 功能描述:
* @param message
* @return: void
* @Author: boo
* @Date: 2021/1/29 11:54
*
* @JmsListener 参数
* destination: 【目的地】 指向哪个队列 一个消费者只能指向一个队列 一个队列可以被多个消费者消费
* 若 多个 消费者同时指向一个队列 在Queue(队列模式)下
* 消费者共消费队列中的信息一遍
* 即队列中的内容被A消费后 就会从队列中移除 不会再让其他消费者重复消费
*/
@JmsListener(destination="${spring.activemq.queue-name}", containerFactory="queueListener")
public void readActiveQueue(String message) {
System.out.println("readActiveQueue接受到:" + message);
}
@JmsListener(destination="${spring.activemq.queue-name}", containerFactory="queueListener")
public void readActiveQueue2(String message) {
System.out.println("readActiveQueue2 接受到:" + message);
}
@JmsListener(destination="queue1", containerFactory="queueListener")
public void readActiveQueueObj(AjaxResult ajaxResult) {
System.out.println("readActiveQueueObj接受到:" + ajaxResult.get("msg"));
}
}
/**topic(订阅模式)的消费者(订阅者)
* 若 多个 消费者同时指向一个队列 在topic(订阅模式)下
* * 队列中的每条信息都会被 消费者 分别消费一次
* * 即队列中的内容被A消费后 不会从队列中移除 还可以被B、C、D消费
* 直到所有的消费者都消费 一次后 移出队列
* description: TopicConsumerListener <br>
* date: 2021/1/28 9:56 <br>
* author: boo<br>
* version: 1.0 <br>
*/
@Component
public class TopicConsumerListener {
//topic模式的消费者
@JmsListener(destination="${spring.activemq.topic-name}", containerFactory="topicListener")
public void readActiveQueue(String message) {
System.out.println("topic接受到:" + message);
}
@JmsListener(destination="${spring.activemq.topic-name}", containerFactory="topicListener")
public void readActiveQueue2(String message) {
System.out.println("topic(readActiveQueue2)接受到:" + message);
}
@JmsListener(destination="topic1", containerFactory="topicListener")
public void readActiveQueue1(String message) {
System.out.println("topic1接受到:" + message);
}
}
7. 测试
- 启动项目(注意要先启动ActiveMq,参考上 一)
- 访问生产者中的地址,例如:
http://localhost:8080/publish/queue/test
控制台将打印如下内容:
- web端可以查看到队列的信息