• SpringBoot 2.x (13):整合ActiveMQ


    ActiveMQ5.x不多做介绍了,主要是SpringBoot的整合

    特点:
    1)支持来自Java,C,C ++,C#,Ruby,Perl,Python,PHP的各种跨语言客户端和协议
    2)支持许多高级功能,如消息组,虚拟目标,通配符和复合目标
    3) 完全支持JMS 1.1和J2EE 1.4,支持瞬态,持久,事务和XA消息
    4) Spring支持,ActiveMQ可以轻松嵌入到Spring应用程序中,并使用Spring的XML配置机制进行配置
    5) 支持在流行的J2EE服务器(如TomEE,Geronimo,JBoss,GlassFish和WebLogic)中进行测试
    6) 使用JDBC和高性能日志支持非常快速的持久化

    下载:

    http://activemq.apache.org/activemq-5153-release.html

    实际开发推荐部署到Linux系统,具体操作网上也有教程

    我这里为了方便,直接安装在本地Windows机器上

    如果想了解更多,查看官方文档:

    http://activemq.apache.org/getting-started.html

    进入bin目录win64目录启动activemq.bat即可

    访问localhost:8161进入首页

    访问http://localhost:8161/admin/进入管理页面,默认用户名和密码都是admin

    整合:

    依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-activemq</artifactId>
            </dependency>

    连接池

            <dependency>
                <groupId>org.apache.activemq</groupId>
                <artifactId>activemq-pool</artifactId>
            </dependency>

    基本的配置

    # ActiveMQ
    spring.activemq.broker-url=tcp://127.0.0.1:61616
    spring.activemq.user=admin
    spring.activemq.password=admin
    spring.activemq.pool.enabled=true
    spring.activemq.pool.max-connections=100

    使用ActiveMQ必须要在SpringBoot启动类中开启JMS,并进行配置

    package org.dreamtech.avtivemq;
    
    import javax.jms.ConnectionFactory;
    
    import org.apache.activemq.ActiveMQConnectionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.core.env.Environment;
    import org.springframework.jms.annotation.EnableJms;
    import org.springframework.jms.core.JmsMessagingTemplate;
    import org.springframework.jms.core.JmsTemplate;
    
    @SpringBootApplication
    @EnableJms
    public class AvtivemqApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(AvtivemqApplication.class, args);
        }
    
        @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;
        }
    
        @Bean
        public JmsTemplate genJmsTemplate() {
            return new JmsTemplate(connectionFactory());
    
        }
    
        @Bean
        public JmsMessagingTemplate jmsMessageTemplate() {
            return new JmsMessagingTemplate(connectionFactory());
        }
    }

    点对点模型:

    首先实现消息的发送

    package org.dreamtech.avtivemq.service;
    
    import javax.jms.Destination;
    
    /**
     * 消息生产
     * 
     * @author Xu Yiqing
     *
     */
    public interface ProducerService {
        /**
         * 使用指定消息队列发送
         * 
         * @param destination
         * @param message
         */
        void sendMsg(Destination destination, final String message);
    }
    package org.dreamtech.avtivemq.service.impl;
    
    import javax.jms.Destination;
    
    import org.dreamtech.avtivemq.service.ProducerService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.core.JmsMessagingTemplate;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ProducerServiceImpl implements ProducerService {
        @Autowired
        private JmsMessagingTemplate jmsTemplate;
    
        @Override
        public void sendMsg(Destination destination, String message) {
            jmsTemplate.convertAndSend(destination, message);
        }
    
    }
    package org.dreamtech.avtivemq.controller;
    
    import javax.jms.Destination;
    
    import org.apache.activemq.command.ActiveMQQueue;
    import org.dreamtech.avtivemq.service.ProducerService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class OrderController {
        @Autowired
        private ProducerService producerService;
        
        @GetMapping("/order")
        private Object order(String msg) {
            Destination destination = new ActiveMQQueue("order.queue");
            producerService.sendMsg(destination,msg);
            return "order";
        }
    }

    访问:http://localhost:8080/order?msg=demo,然后查看ActiveMQ界面:

    有生产者就就有消费者:监听消息队列

    package org.dreamtech.avtivemq.jms;
    
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class OrderConsumer {
        /**
         * 监听指定消息队列
         * 
         * @param text
         */
        @JmsListener(destination = "order.queue")
        public void receiveQueue(String text) {
            System.out.println("[ OrderConsumer收到的报文 : " + text + " ]");
        }
    }

    由于实时监听,一启动SpringBoot就会打印:

    [ OrderConsumer收到的报文 : demo ]

    发布订阅模型:比如抖音小视频,某网红发布新视频,多名粉丝收到消息

    默认ActiveMQ只支持点对点模型,想要开启发布订阅模型,需要进行配置

    spring.jms.pub-sub-domain=true

    Spring管理主题对象

        @Bean
        public Topic topic() {
            return new ActiveMQTopic("demo.topic");
        }

    发布者

        /**
         * 消息发布者
         * 
         * @param msg
         */
        void publish(String msg);
        @Autowired
        private JmsMessagingTemplate jmsTemplate;
        @Autowired
        private Topic topic;
    
        @Override
        public void publish(String msg) {
            jmsTemplate.convertAndSend(topic, msg);
        }
        @Autowired
        private ProducerService producerService;
        @GetMapping("/topic")
        private Object topic(String msg) {
            producerService.publish(msg);
            return "success";
        }

    订阅者(消费者):一人发布,多人订阅

    package org.dreamtech.avtivemq.jms;
    
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class TopicConsumer {
        @JmsListener(destination = "demo.topic")
        public void receiver1(String text) {
            System.out.println("TopicConsumer : receiver1 : " + text);
        }
    
        @JmsListener(destination = "demo.topic")
        public void receiver2(String text) {
            System.out.println("TopicConsumer : receiver2 : " + text);
        }
    
        @JmsListener(destination = "demo.topic")
        public void receiver3(String text) {
            System.out.println("TopicConsumer : receiver3 : " + text);
        }
    }

    启动项目,访问:

    http://localhost:8080/topic?msg=666

    打印如下

    TopicConsumer : receiver1 : 666
    TopicConsumer : receiver3 : 666
    TopicConsumer : receiver2 : 666

    那么点对点和发布订阅模型可以一起使用吗?

    不可以

    如何配置?

    1.注释掉 #spring.jms.pub-sub-domain=true

    2.加入Bean:给topic定义独立的JmsListenerContainer

        @Bean
        public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
            DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
            bean.setPubSubDomain(true);
            bean.setConnectionFactory(activeMQConnectionFactory);
            return bean;
        }

    3.@JmsListener如果不指定独立的containerFactory的话是只能消费queue消息

        @JmsListener(destination = "demo.topic", containerFactory = "jmsListenerContainerTopic")
        public void receiver1(String text) {
            System.out.println("TopicConsumer : receiver1 : " + text);
        }
  • 相关阅读:
    Codeforces Round #609 (Div. 2)---C. Long Beautiful Integer
    Codeforces Round #609 (Div. 2)--B.Modulo Equality
    J
    G
    Convoy
    Farming Mars
    Java indexOf() 方法
    request.getContextPath()得到的是什么路径?
    OLAP、OLTP的介绍和比较
    Book recommendation
  • 原文地址:https://www.cnblogs.com/xuyiqing/p/10851859.html
Copyright © 2020-2023  润新知