一起来学SpingBoot(二十)消息队列ActiveMq

序言

​ ActiveMQ是Apache所提供的一个开源的消息系统,完全采用Java来实现,因此,它能很好地支持J2EE提出的JMS(Java Message Service,即Java消息服务)规范。JMS是一组Java应用程序接口,它提供消息的创建、发送、读取等一系列服务,虽然比较老,但是依然可以运用于中小项目的生产环境。

JMS

JMS支持两种消息发送和接收模型。

P2P(Ponit to Point)

​ 即采用点对点的方式发送消息。P2P模型是基于队列的,消息生产者发送消息到队列,消息消费者从队列中接收消息,队列的存在使得消息的异步传输称为可能,P2P模型在点对点的情况下进行消息传递时采用。

Pub/Sub(Publish/Subscribe

​ 发布-订阅模型定义了如何向一个内容节点发布和订阅消息,这个内容节点称为topic(主题)。主题可以认为是消息传递的中介,消息发布这将消息发布到某个主题,而消息订阅者则从主题订阅消息。主题使得消息的订阅者与消息的发布者互相保持独立,不需要进行接触即可保证消息的传递,发布-订阅模型在消息的一对多广播时采用。

使用

怎么在SpringBoot中使用呢?加入如下依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!-- 连接外部mq-->
<dependency>
   <groupId>org.messaginghub</groupId>
   <artifactId>pooled-jms</artifactId>
</dependency>

默认spring-boot-starter-activemq 会内直一个ActiveMq,咱们这次用外置的,加入pooled-jms即可。

然后在yml中配置

spring:
  activemq:
    broker-url: tcp://localhost:61616
    close-timeout: 5000
    in-memory: false
    user: admin
    password: 'admin'
    pool:
      enabled: true
      max-connections: 100
    send-timeout: 3000
 

然后呢就是创建队列

@Configuration
@EnableJms
public class ActiveMqConfig {

    private static final String QUEUE_NAME = "queueTest";

    /**
     * 定义存放消息的队列
     *
     * @return
     */
    @Bean
    public Queue queueTest() {
        return new ActiveMQQueue(QUEUE_NAME);
    }

}

在然后spring-boot-starter-activemq 内直了一个 jmsMessagingTemplate 方便我们去发送消息

@RestController
public class SendController {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private Queue queueTest;

    /**
     * 发送消息
     *
     * @param value
     */
    @GetMapping("queue")
    public void jmsQueueTemplate(@RequestParam String value) {
        jmsMessagingTemplate.convertAndSend(queueTest, value);
    }

}

这样发就可以啦 !

然后在创立一个消息的监听者

@Component
@Slf4j
public class QueueReceiver { 
   
   @JmsListener(destination = "queueTest")
    public void receive(String msg) {
         log.info("queueTest  queue1 监听到的消息内容为: " + msg);
    }
   
}   

其中@JmsListener 标注是一个消息的监听方法,然后destination = "queueTest" 指的就是怎么队列的名字。

那么如何使用消息队列中的发布订阅呢?很简单只需要改一下队列的bean即可

@Configuration
@EnableJms
public class ActiveMqConfig {

    private static final String TOPIC_NAME = "topicTest";

    //发布订阅队列
    @Bean
    public Topic topicTest() {
        return new ActiveMQTopic(TOPIC_NAME);
    }
}

然后在controller里使用即可

@RestController
public class SendController {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private Topic topicTest;

    /**
     * 发送消息
     *
     * @param value
     */
    @GetMapping("topic")
    public void jmsTopicTemplate(@RequestParam String value) {
        jmsMessagingTemplate.convertAndSend(topicTest, value);
    }

}

接收消息的监听也只是改一改队列的名字就行了

@Component
@Slf4j
public class QueueReceiver {
	
    @JmsListener(destination = "topicTest")
    public void topicReceive1(String msg) {
        log.info("topicTest 1 监听到的消息内容为: " + msg);
    }
}

结果就是发送失败,因为SpringBoot默认提供的连接工厂不支持发布订阅,所以要在yml里这样设置一下

spring:
  activemq:
    broker-url: tcp://localhost:61616
    close-timeout: 5000
    in-memory: false
    password: 'admin'
    pool:
      enabled: true
      max-connections: 100
    send-timeout: 3000
    user: admin
    non-blocking-redelivery: true
  jms:
    pub-sub-domain: true

但是这样也太不方便了吧。

我两个都想使用怎么办呢?对 我们自己定义一下连接工厂就行了。

首先呢定义两个连接工厂

@Configuration
@EnableJms
public class ActiveMqConfig {

    /**
     * topic模式的ListenerContainer
     *
     * @return
     */
    @Bean
    public JmsListenerContainerFactory<?> topicListenerFactory() {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        ActiveMQConnectionFactory connectionFactor = new ActiveMQConnectionFactory();
        factory.setPubSubDomain(true);
        factory.setConnectionFactory(connectionFactor);
        return factory;
    }

    /**
     * queue模式的ListenerContainer
     *
     * @return
     */
    @Bean
    public JmsListenerContainerFactory<?> queueListenerFactory() {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        ActiveMQConnectionFactory connectionFactor = new ActiveMQConnectionFactory();
        factory.setPubSubDomain(false);
        factory.setConnectionFactory(connectionFactor);
        return factory;
    }


}

其中呢factory.setPubSubDomain(true) 就代表是一个发布订阅的连接工厂,factory.setPubSubDomain(false) 则是默认队列的连接工厂,在监听方法中这样使用即可。

@Component
@Slf4j
public class QueueReceiver {

    @JmsListener(destination = "queueTest", containerFactory = "queueListenerFactory")
    public void receive2(String msg) {
        log.info("queueTest queue2 监听到的消息内容为: " + msg);
    }

    @JmsListener(destination = "topicTest", containerFactory = "topicListenerFactory")
    public void topicReceive1(String msg) {
        log.info("topicTest 1 监听到的消息内容为: " + msg);
    }
}
   

此外还有很多细节用法,还是那句话建议大家多去官网看看文档,这才是解决问题和提升自己的关键所在啊。

本博文是基于springboot2.x 如果有什么不对的请在下方留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值