ActiveMQ

ActiveMQ

一、 ActiveMQ 简介

1 什么是 ActiveMQ

ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现,尽管 JMS 规范出台已经是很久的事情了,但是 JMS 在当今的 J2EE 应用中间仍然扮演着特殊的地位。

2 什么是消息

“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。

3 什么是队列

在这里插入图片描述

4 什么是 消息 队列

“消息队列”是在消息的传输过程中保存消息的容器。

5 常用消息服务应用

5.1ActiveMQ

ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现。

5.2RabbitMQ

RabbitMQ 是一个在 AMQP 基础上完成的,可复用的企业消息系统。他遵循 Mozilla PublicLicense 开源协议。开发语言为 Erlang。

5.3RocketMQ

由阿里巴巴定义开发的一套消息队列应用服务。

二、 消息 服务 的应用场景

消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦和。

在这里插入图片描述

5.1 异步处理
5.1.1 用户注册

用户注册流程:
1)注册处理以及写数据库
2)发送注册成功的手机短信
3)发送注册成功的邮件信息
如果用消息中间件:则可以创建两个线程来做这些事情,直接发送消息给消息中间件,然后让邮件服务和短信服务自己去消息中间件里面去取消息,然后取到消息后再自己做对应的业务操作。就是这么方便

5.2 应用的解耦
5.2.1 订单处理

生成订单流程:
1)在购物车中点击结算
2)完成支付
3)创建订单
4)调用库存系统
订单完成后,订单系统并不去直接调用库存系统,而是发送消息到消息中间件,写入一个订单信息。库存系统自己去消息中间件上去获取,然后做发货处理,并更新库存,这样能够实现互联网型应用追求的快这一个属性。而库存系统读取订单后库存应用这个操作也是非常快的,所以有消息中间件对解耦来说也是一个不错的方向。

5.3 流量的削峰
5.3.1 秒杀功能

秒杀流程:
1)用户点击秒杀
2)发送请求到秒杀应用
3)在请求秒杀应用之前将请求放入到消息队列
4)秒杀应用从消息队列中获取请求并处理。
比如,系统举行秒杀活动,热门商品。流量蜂拥而至 100 件商品,10 万人挤进来怎么办?10 万秒杀的操作,放入消息队列。秒杀应用处理消息队列中的 10 万个请求中的前 100个,其他的打回,通知失败。流量峰值控制在消息队列处,秒杀应用不会瞬间被怼死.

三、 JMS

1 什么是 JMS

JMS(Java Messaging Service)是 Java 平台上有关面向消息中间件的技术规范,它便于消息系统中的 Java 应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口,简化企业应用的开发。

2 JMS 模型

2.1 点对点模型(Point ToPoint)

生产者发送一条消息到 queue,只有一个消费者能收到。

在这里插入图片描述

2.2 发布订阅模型(Publish/Subscribe)

发布者发送到 topic 的消息,只有订阅了 topic 的订阅者才会收到消息。

在这里插入图片描述

四、 ActiveMQ 安装

1 下载资源

ActiveMQ 官网: http://activemq.apache.org

1.1 版本说明

ActiveMQ5.10.x 以上版本必须使用 JDK1.8 才能正常使用。
ActiveMQ5.9.x 及以下版本使用 JDK1.7 即可正常使用。

2 上传至 Linux 服务器

在这里插入图片描述

3 解压安装文件

tar -zxf apache-activemq-5.9.0-bin.tar.gz

在这里插入图片描述

4 检查权限

ls -al apache-activemq-5.9.0/bin
如果权限不足,则无法执行,需要修改文件权限:
chmod 755 activemq

不同Linux环境权限不同,centOS8版本的Linux为可执行不用授权

在这里插入图片描述

5 复制应用至本地目录

cp -r apache-activemq-5.9.0 /usr/local/activemq

在这里插入图片描述

6 启动 ActiveMQ

/usr/local/activemq/bin/activemq start

在这里插入图片描述

7 测试 ActiveMQ

7.1 检查进程

ps aux | grep activemq
见到下述内容即代表启动成功

在这里插入图片描述

7.2 管理界面

使用浏览器访问 ActiveMQ 管理应用, 地址如下:
http://ip:8161/admin/

关闭虚拟机防火墙

用户名: admin
密码: admin
ActiveMQ 使用的是 jetty 提供 HTTP 服务.启动稍慢,建议短暂等待再访问测试.
见到如下界面代表服务启动成功

在这里插入图片描述

在这里插入图片描述

7.3 修改访问端口

修改 ActiveMQ 配置文件: /usr/local/activemq/conf/jetty.xml

配置文件修改完毕,保存并重新启动 ActiveMQ 服务。

在这里插入图片描述

在这里插入图片描述

7.4 修改用户名和密码

修改 conf/users.properties 配置文件.内容为: 用户名=密码
保存并重启 ActiveMQ 服务即可.

在这里插入图片描述

8 重启 ActiveMQ

/usr/local/activemq/bin/activemq restart

9 关闭 ActiveMQ

/usr/local/activemq/bin/activemq stop

10 配置文件 activemq.xml

配置文件中,配置的是 ActiveMQ 的核心配置信息. 是提供服务时使用的配置. 可以修改启动的访问端口. 即 java 编程中访问 ActiveMQ 的访问端口.
默认端口为 61616.
使用协议是: tcp 协议.
修改端口后, 保存并重启 ActiveMQ 服务即可.

在这里插入图片描述

在这里插入图片描述

11 ActiveMQ 目录介绍

从它的目录来说,还是很简单的:

  • bin 存放的是脚本文件

  • conf 存放的是基本配置文件

  • data 存放的是日志文件

  • docs 存放的是说明文档

  • examples 存放的是简单的实例

  • lib 存放的是 activemq 所需 jar 包

  • webapps 用于存放项目的目录

    在这里插入图片描述

    五、 ActiveMQ 术语

    1 Destination

    目的地,JMS Provider(消息中间件)负责维护,用于对 Message 进行管理的对象。
    MessageProducer 需要指定 Destination 才能发送消息,MessageReceiver 需要指定 Destination
    才能接收消息。

    2 Producer

    消息生成者,负责发送 Message 到目的地。

    3 Consumer | Receiver

    消息消费者,负责从目的地中消费【处理|监听|订阅】Message。

    4 Message

    消息,消息封装一次通信的内容。

    六、 ActiveMQ 应用

    1 ActiveMQ 常用 API 简介

    下述 API 都是接口类型,由定义在 javax.jms 包中.是 JMS 标准接口定义.

    1.1ConnectionFactory

    链接工厂, 用于创建链接的工厂类型.

    1.2Connection

    链接. 用于建立访问 ActiveMQ 连接的类型, 由链接工厂创建.

    1.3Session

    会话, 一次持久有效有状态的访问. 由链接创建.

    1.4Destination & Queue

    目的地, 用于描述本次访问 ActiveMQ 的消息访问目的地. 即 ActiveMQ 服务中的具体队列. 由会话创建.
    interface Queue extends Destination

    1.5MessageProducer

    消息生成者, 在一次有效会话中, 用于发送消息给 ActiveMQ 服务的工具. 由会话创建.

    1.6MessageConsumer

    消息消费者【消息订阅者,消息处理者】, 在一次有效会话中, 用于从 ActiveMQ 服务中获取消息的工具. 由会话创建.

    1.7Message

    消息, 通过消息生成者向 ActiveMQ 服务发送消息时使用的数据载体对象或消息消费者从 ActiveMQ 服务中获取消息时使用的数据载体对象. 是所有消息【文本消息,对象消息等】具体类型的顶级接口. 可以通过会话创建或通过会话从 ActiveMQ 服务中获取.

    2 JMS-HelloWorld

    2.1 处理文本消息
    2.1.1 创建 消息 生产 者
    2.1.1.1 创建工程

在这里插入图片描述

2.1.1.2 修改 POM 文件添加 ActiveMQ

添加依赖的版本要和按照的版本一致

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>mq-producer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.9.0</version>
        </dependency>

    </dependencies>

</project>
2.1.1.3 编写消息的生产者

ActiveMQ默认提供两个用户

在这里插入图片描述

package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldProducer {
    /**
     * 生产消息
     */
    public void sendHelldWorldActiveMQ(String msgTest) {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的发送者
        MessageProducer producer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createQueue("helloworld-destination");

            //创建消息的生产者
            producer = session.createProducer(destination);

            //创建消息对象    文本类型的消息
            message = session.createTextMessage(msgTest);

            //发送消息
            producer.send(message);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //回收消息发送者资源
            if (producer != null) {//防止出现空指针异常
                try {
                    producer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
2.1.2 创建消息消费者
2.1.2.1 创建工程

在这里插入图片描述

2.1.2.2 修改 POM 文件添加 ActiveMQ
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>mq-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.9.0</version>
        </dependency>

    </dependencies>

</project>
2.1.2.3 编写消息的消费者
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldConsumer {
    /**
     * 消费消息
     */
    public void readHelldWorldActiveMQ() {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的消费者
        MessageConsumer consumer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createQueue("helloworld-destination");

            //创建消息的消费者
            consumer = session.createConsumer(destination);

            //创建消息对象    文本类型的消息
            message = consumer.receive();

            // 处理消息     强转成Text类型对象,然后获取字符串对象
            String msg = ((TextMessage) message).getText();
            System.out.println("从ActiveMQ中获取的文本信息:	"+msg);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //回收消息发送者资源
            if (consumer != null) {//防止出现空指针异常
                try {
                    consumer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
2.1.3 测试
2.1.3.1 Producer
package com.bjsxt;

public class Test {
    public static void main(String[] args) {
        HelloWorldProducer producer = new HelloWorldProducer();
        producer.sendHelldWorldActiveMQ("Hello World");
    }
}

在这里插入图片描述

在这里插入图片描述

2.1.3.2 Consumer
package com.bjsxt;

public class Test {
    public static void main(String[] args) {
        HelloWorldConsumer consumer = new HelloWorldConsumer();
        consumer.readHelldWorldActiveMQ();
    }
}

在这里插入图片描述

消息被消费之后消息队列中没有消息了

在这里插入图片描述

2.2 处理对象消息
2.2.1 定义消息对象

只要对象需要在网络上传输时对象必须实现可序列化接口

package com.bjsxt;

import java.io.Serializable;

public class Users implements Serializable {
    private int userid;
    private String username;
    private int userage;

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getUserage() {
        return userage;
    }

    public void setUserage(int userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", userage=" + userage +
                '}';
    }
}
2.2.2 创建生产者
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldProducer2 {
    /**
     * 生产消息
     */
    public void sendHelldWorldActiveMQ(Users users) {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的发送者
        MessageProducer producer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createQueue("my-users");

            //创建消息的生产者
            producer = session.createProducer(destination);

            //创建消息对象    对象类型的消息
            message = session.createObjectMessage(users);

            //发送消息
            producer.send(message);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //回收消息发送者资源
            if (producer != null) {//防止出现空指针异常
                try {
                    producer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
2.2.3 定义消息消费者
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldConsumer2 {
    /**
     * 消费消息
     */
    public void readHelldWorldActiveMQ() {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的消费者
        MessageConsumer consumer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createQueue("my-users");

            //创建消息的消费者
            consumer = session.createConsumer(destination);

            //创建消息对象    文本类型的消息
            message = consumer.receive();

            // 处理消息     强转成Users类型对象,然后获取字符串对象
            ObjectMessage objMessage = (ObjectMessage) message;
            Users users = (Users) objMessage.getObject();
            System.out.println(users);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //回收消息发送者资源
            if (consumer != null) {//防止出现空指针异常
                try {
                    consumer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

测试

package com.bjsxt;

public class Test {
    public static void main(String[] args) {
        /*HelloWorldProducer producer = new HelloWorldProducer();
        producer.sendHelldWorldActiveMQ("Hello World");*/

        Users users = new Users();
        users.setUserid(1);
        users.setUsername("临江仙");
        users.setUserage(23);
        HelloWorldProducer2 producer2 = new HelloWorldProducer2();
        producer2.sendHelldWorldActiveMQ(users);
    }
}
package com.bjsxt;

public class Test {
    public static void main(String[] args) {
        /*HelloWorldConsumer consumer = new HelloWorldConsumer();
        consumer.readHelldWorldActiveMQ();*/

        HelloWorldConsumer2 consumer2 = new HelloWorldConsumer2();
        consumer2.readHelldWorldActiveMQ();
    }
}

在这里插入图片描述

3 JMS - 实现队列服务监听

队列服务监听使用的观察者设计模式

3.1 创建消息生产者
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldProducer3 {
    /**
     * 生产消息
     */
    public void sendHelldWorldActiveMQ(String msgTest) {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的发送者
        MessageProducer producer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createQueue("my-destination");

            //创建消息的生产者
            producer = session.createProducer(destination);

            //创建消息对象    文本类型的消息
            message = session.createTextMessage(msgTest);

            //发送消息
            producer.send(message);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //回收消息发送者资源
            if (producer != null) {//防止出现空指针异常
                try {
                    producer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
3.2消息消费者

保持线程是活的,不能关闭各种资源,否则consumer都死掉了就没人消费消息了 注意去掉了finally中关闭资源的代码,保证consumer时时监听就可以做到producer生产一个消息consumer消费一个消息

package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldConsumer3 {
    /**
     * 消费消息
     */
    public void readHelldWorldActiveMQ() {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的消费者
        MessageConsumer consumer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createQueue("my-destination");

            //创建消息的消费者
            consumer = session.createConsumer(destination);

            consumer.setMessageListener(new MessageListener() {
                //ActiveMQ回调的方法。通过该方法将消息传递到consumer中
                @Override
                public void onMessage(Message message) {
                    // 处理消息     强转成Text类型对象,然后获取字符串对象
                    String msg = null;
                    try {
                        msg = ((TextMessage) message).getText();
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                    System.out.println("从ActiveMQ中获取的文本信息:      "+msg);
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4 Topic 模型

4.1Publish/Subscribe 处理模式(Topic )

消息生产者(发布)将消息发布到 topic 中,同时有多个消息消费者(订阅)消费该消息。
和点对点方式不同,发布到 topic 的消息会被所有订阅者消费。

当生产者发布消息,不管是否有消费者。都不会保存消息一定要先有消息的消费者,后有消息的生产者。

消息的生产者发送完不管

4.2创建生产者
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldProducerTopic {
    /**
     * 生产消息
     */
    public void sendHelldWorldActiveMQ(String msgTest) {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的发送者
        MessageProducer producer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,使用发布订阅模式
            destination = session.createTopic("test_topic");

            //创建消息的生产者
            producer = session.createProducer(destination);

            //创建消息对象    文本类型的消息
            message = session.createTextMessage(msgTest);

            //发送消息
            producer.send(message);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //回收消息发送者资源
            if (producer != null) {//防止出现空指针异常
                try {
                    producer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
4.3创建消费者
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldConsumerTopic1 implements Runnable{
    /**
     * 消费消息
     */
    public void readHelldWorldActiveMQ() {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的消费者
        MessageConsumer consumer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createTopic("test-topic");

            //创建消息的消费者
            consumer = session.createConsumer(destination);

            consumer.setMessageListener(new MessageListener() {
                //ActiveMQ回调的方法。通过该方法将消息传递到consumer中
                @Override
                public void onMessage(Message message) {
                    // 处理消息     强转成Text类型对象,然后获取字符串对象
                    String msg = null;
                    try {
                        msg = ((TextMessage) message).getText();
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                    System.out.println("从ActiveMQ中获取的文本信息 --- topic1:      "+msg);
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        this.readHelldWorldActiveMQ();
    }
}
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldConsumerTopic2 implements Runnable{
    /**
     * 消费消息
     */
    public void readHelldWorldActiveMQ() {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的消费者
        MessageConsumer consumer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地,目的地名称即队列名称。消息的消费者需要通过此名称访问对应的队列
            destination = session.createTopic("test-topic");

            //创建消息的消费者
            consumer = session.createConsumer(destination);

            consumer.setMessageListener(new MessageListener() {
                //ActiveMQ回调的方法。通过该方法将消息传递到consumer中
                @Override
                public void onMessage(Message message) {
                    // 处理消息     强转成Text类型对象,然后获取字符串对象
                    String msg = null;
                    try {
                        msg = ((TextMessage) message).getText();
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                    System.out.println("从ActiveMQ中获取的文本信息 --- topic2:      "+msg);
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        this.readHelldWorldActiveMQ();
    }
}
package com.bjsxt;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class HelloWorldConsumerTopic3 implements Runnable{
    /**
     * 消费消息
     */
    public void readHelldWorldActiveMQ() {
        //定义连接工厂
        ConnectionFactory connectionFactory = null;

        //定义链接对象
        Connection connection = null;

        //定义会话
        Session session = null;

        //目的地
        Destination destination = null;

        //定义消息的消费者
        MessageConsumer consumer = null;

        //定义消息
        Message message = null;

        try {
            /**
             * userName:访问ActiveMQ服务的用户名    默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * password:访问ActiveMQ服务的密码     默认的为admin,用户名可以通过jetty-ream.properties文件进行修改
             * brokerURL:访问ActiveMQ服务的路径地址。路径结构为  -  协议名://主机地址:端口号
             */
            connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.88.101:61616");
            //创建链接对象
            connection = connectionFactory.createConnection();
            //启动链接
            connection.start();
            //创建会话
            /**
             * transacted:是否使用事务,可选值为    true  |  false
             *            true:使用事务。当设置此变量值时,acknowledgeMode变量值为:Session.SESSION_TRANSACTED
             *            false:不使用事务,当设置此变量值时,acknowledgeMode参数必须设置
             * acknowledgeMode:
             *
             * Session.AUTO_ACKNOWLEDGE:自动确认机制
             * CLIENT_ACKNOWLEDGE:客户端确认机制
             *DUPS_OK_ACKNOWLEDGE:有副本的客户端消息确认机制。    前两种一旦受到消费端的消息确认之后消息队列会把消息从队列中删除
             *                                                第三种即便是收到了消息确认之后也不会删除,一直缓存称为有副本
             *
             */
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //创建目的地
            destination = session.createTopic("test-topic");

            //创建消息的消费者
            consumer = session.createConsumer(destination);

            consumer.setMessageListener(new MessageListener() {
                //ActiveMQ回调的方法。通过该方法将消息传递到consumer中
                @Override
                public void onMessage(Message message) {
                    // 处理消息     强转成Text类型对象,然后获取字符串对象
                    String msg = null;
                    try {
                        msg = ((TextMessage) message).getText();
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                    System.out.println("从ActiveMQ中获取的文本信息 --- topic3:      "+msg);
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        this.readHelldWorldActiveMQ();
    }
}
package com.bjsxt;

public class Test {
    public static void main(String[] args) {
        /*HelloWorldProducer producer = new HelloWorldProducer();
        producer.sendHelldWorldActiveMQ("Hello World");*/

        /*HelloWorldProducer3 producer3 = new HelloWorldProducer3();
        producer3.sendHelldWorldActiveMQ("临江仙");*/

        HelloWorldProducerTopic topic = new HelloWorldProducerTopic();
        topic.sendHelldWorldActiveMQ("Hello Topic");
    }
}
package com.bjsxt;

public class Test {
    public static void main(String[] args) {
        /*HelloWorldConsumer consumer = new HelloWorldConsumer();
        consumer.readHelldWorldActiveMQ();*/

        /*HelloWorldConsumer2 consumer2 = new HelloWorldConsumer2();
        consumer2.readHelldWorldActiveMQ();*/

        /*HelloWorldConsumer3 consumer3 = new HelloWorldConsumer3();
        consumer3.readHelldWorldActiveMQ();*/

        HelloWorldConsumerTopic1 topic1 = new HelloWorldConsumerTopic1();
        Thread t1 = new Thread(topic1);
        t1.start();

        HelloWorldConsumerTopic2 topic2 = new HelloWorldConsumerTopic2();
        Thread t2 = new Thread(topic2);
        t2.start();

        HelloWorldConsumerTopic3 topic3 = new HelloWorldConsumerTopic3();
        Thread t3 = new Thread(topic3);
        t3.start();
    }
}

在这里插入图片描述

七、 Spring 整合 ActiveMQ

1 创建 spring-activemq-producer

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

parent/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.bjsxt</groupId>
   <artifactId>parent</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>pom</packaging>

   <!-- 对依赖的jar包的版本统一进行定义 -->
   <properties>
      <activemq.version>5.9.0</activemq.version>
      <xbean.version>4.5</xbean.version>
      <jms.version>4.1.6.RELEASE</jms.version>
      <activemq-pool.version>5.9.0</activemq-pool.version>
      <solrj.version>4.10.3</solrj.version>
      <jedis.version>2.9.0</jedis.version>
      <junit.version>4.12</junit.version>
      <spring.version>4.1.3.RELEASE</spring.version>
      <mybatis.version>3.2.8</mybatis.version>
      <mybatis.spring.version>1.2.2</mybatis.spring.version>
      <mysql.version>5.1.32</mysql.version>
      <slf4j.version>1.6.4</slf4j.version>
      <druid.version>1.0.9</druid.version>
      <jstl.version>1.2</jstl.version>
      <servlet-api.version>2.5</servlet-api.version>
      <tomcat.version>2.2</tomcat.version>
      <jsp-api.version>2.0</jsp-api.version>
      <zkClient-version>0.10</zkClient-version>
      <dubbo-version>2.5.4</dubbo-version>
      <jackson.version>2.4.2</jackson.version>
      <commons-net.version>3.3</commons-net.version>
      <commons-fileupload.version>1.3.1</commons-fileupload.version>
   </properties>


   <!-- jar包的依赖注入 ,由于该工程是一个父工程,所以jar包在该pom文件中只是声明 -->
   <dependencyManagement>
      <dependencies>
      <!-- ActiveMQ客户端完整jar包依赖 -->
      <dependency>
         <groupId>org.apache.activemq</groupId>
         <artifactId>activemq-all</artifactId>
         <version>${activemq.version}</version>
      </dependency>
      <!-- ActiveMQ和Spring整合配置文件标签处理jar包依赖 -->
      <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-spring</artifactId>
         <version>${xbean.version}</version>
      </dependency>
      <!-- Spring-JMS插件相关jar包依赖 -->
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-jms</artifactId>
         <version>${jms.version}</version>
      </dependency>
      <!-- Spring-JMS插件相关jar包依赖 -->
      <dependency>
          <groupId>org.apache.activemq</groupId>
          <artifactId>activemq-pool</artifactId>
          <version>${activemq-pool.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.activemq</groupId>
          <artifactId>activemq-jms-pool</artifactId>
          <version>${activemq-pool.version}</version>
      </dependency>
      
      <dependency>
         <groupId>org.apache.solr</groupId>
         <artifactId>solr-solrj</artifactId>
         <version>${solrj.version}</version>
      </dependency>
      <dependency>
         <groupId>redis.clients</groupId>
         <artifactId>jedis</artifactId>
         <version>${jedis.version}</version>
      </dependency>
         <!-- 单元测试 -->
         <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
         </dependency>
         <!-- 日志处理 -->
         <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
         </dependency>
         <!-- Mybatis -->
         <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
         </dependency>
         <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis.spring.version}</version>
         </dependency>
         <!-- MySql -->
         <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
         </dependency>
         <!-- 连接池 -->
         <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
         </dependency>
         <!-- Spring -->
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
         </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
         </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
         </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
         </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
         </dependency>
         <!-- JSP相关 -->
         <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
         </dependency>
         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>${servlet-api.version}</version>
            <scope>provided</scope>
         </dependency>
         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>${jsp-api.version}</version>
            <scope>provided</scope>
         </dependency>
         <!-- 文件上传组件 -->
         <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons-fileupload.version}</version>
         </dependency>
         
         <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>${commons-net.version}</version>
         </dependency>
         
         <!-- Jackson Json处理工具包 -->
         <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
         </dependency>
      </dependencies>
   </dependencyManagement>

   <build>
      <resources>
         <resource>
            <directory>src/main/java</directory>
            <includes>
               <include>**/*.xml</include>
            </includes>
         </resource>
         <resource>
            <directory>src/main/resources</directory>
            <includes>
               <include>**/*.xml</include>
               <include>**/*.properties</include>
            </includes>
         </resource>
      </resources>
      <!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
      <pluginManagement>
         <plugins>
            <!-- 配置Tomcat插件 -->
            <plugin>
               <groupId>org.apache.tomcat.maven</groupId>
               <artifactId>tomcat7-maven-plugin</artifactId>
               <version>${tomcat.version}</version>
            </plugin>
         </plugins>
      </pluginManagement>
   </build>
</project>
1.1 修改 POM 文件

重点的三个坐标

spring-activemq-producer/pom.xml

<!-- ActiveMQ 客户端完整 jar 包依赖 -->
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
</dependency>
<!-- ActiveMQ和Spring整合配置文件标签处理jar
包依赖 -->
<dependency>
    <groupId>org.apache.xbean</groupId>
    <artifactId>xbean-spring</artifactId>
</dependency>
<!-- Spring-JMS 插件相关 jar 包依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.bjsxt</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.bjsxt</groupId>
    <artifactId>spring-activemq-producer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <dependencies>
        <!-- ActiveMQ 客户端完整 jar 包依赖 -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
        </dependency>
        <!-- ActiveMQ和Spring整合配置文件标签处理jar
        包依赖 -->
        <dependency>
            <groupId>org.apache.xbean</groupId>
            <artifactId>xbean-spring</artifactId>
        </dependency>
        <!-- Spring-JMS 插件相关 jar 包依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <!-- Spring-JMS插件相关jar包依赖 -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-pool</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-jms-pool</artifactId>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!-- 日志处理 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <!-- JSP 相关 -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 配置 Tomcat 插件 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <path>/</path>
                    <port>8080</port>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>
1.2 整合 ActiveMQ

applicationContext-jms.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jms="http://www.springframework.org/schema/jms"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:amq="http://activemq.apache.org/schema/core"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/jms
      http://www.springframework.org/schema/jms/spring-jms.xsd
      http://activemq.apache.org/schema/core
      http://activemq.apache.org/schema/core/activemq-core.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd">


   <!-- 需要创建一个连接工厂,连接ActiveMQ. ActiveMQConnectionFactory. 需要依赖ActiveMQ提供的amq标签 -->
   <!-- amq:connectionFactory 是bean标签的子标签, 会在spring容器中创建一个bean对象. 可以为对象命名. 
      类似: <bean id="" class="ActiveMQConnectionFactory"></bean> -->
   <amq:connectionFactory brokerURL="tcp://192.168.88.101:61616"
      userName="admin" password="admin" id="amqConnectionFactory" />
      
   <!-- 配置池化的ConnectionFactory。 为连接ActiveMQ的connectionFactory提供连接池 -->
   <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
      <property name="connectionFactory" ref="amqConnectionFactory"></property>
      <property name="maxConnections" value="10"></property>
   </bean>
   <!-- spring管理JMS相关代码的时候,必须依赖jms标签库. spring-jms提供的标签库. -->
   <!-- 定义Spring-JMS中的连接工厂对象 CachingConnectionFactory - spring框架提供的连接工厂对象. 
      不能真正的访问MOM容器. 类似一个工厂的代理对象. 需要提供一个真实工厂,实现MOM容器的连接访问. -->
   <!-- 配置有缓存的ConnectionFactory,session的缓存大小可定制。 -->
   <bean id="connectionFactory"
      class="org.springframework.jms.connection.CachingConnectionFactory">
      <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
      <property name="sessionCacheSize" value="3"></property>
   </bean>

   <!-- JmsTemplate配置 -->
   <bean id="template" class="org.springframework.jms.core.JmsTemplate">
      <!-- 给定连接工厂, 必须是spring创建的连接工厂. -->
      <property name="connectionFactory" ref="connectionFactory"></property>
      <!-- 可选 - 默认目的地命名 -->
      <property name="defaultDestinationName" value="test-spring"></property>
   </bean>
</beans>

applicationContext-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
   <context:property-placeholder location="classpath:resource.properties"/>
   <!-- 扫描bean对象 -->
   <context:component-scan base-package="com.bjsxt.service"/>
</beans>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
      <!-- 包的扫描器主要是扫描@controller -->
      <context:component-scan base-package="com.bjsxt.web.controller"/>  

      <!-- 注册两个新对象 主要是为了来处理springmvc中的其他anntation 如:@requestmapping -->   
      <mvc:annotation-driven/>
      
      <!-- 视图解析器 -->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp/" /><!-- jsp所在的前缀 -->
      <property name="suffix" value=".jsp" />
    </bean>
    <!-- 配置静态资源映射 -->
    <mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
   <mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">
   <!-- 上下文参数,告诉Spring配置文件路径 -->
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext-*.xml</param-value>
   </context-param>
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <!-- 配置springmvc -->
   <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:springmvc.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <url-pattern>/</url-pattern>
   </servlet-mapping>

   <filter>
      <filter-name>encoding</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
         <param-name>encoding</param-name>
         <param-value>utf-8</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>encoding</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>


   <welcome-file-list>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>default.html</welcome-file>
      <welcome-file>default.htm</welcome-file>
      <welcome-file>default.jsp</welcome-file>
   </welcome-file-list>
</web-app>

addUser.jsp

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2021/1/5
  Time: 15:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/user/addUser" method="post">
        ID:<input type="text" name="userid"/><br/>
        姓名:<input type="text" name="username"/><br/>
        年龄:<input type="text" name="userage"/><br/>
        邮箱:<input type="text" name="useremail"/><br/>
        <input type="submit" value="OK"/>
    </form>
</body>
</html>

ok.jsp

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2021/1/5
  Time: 15:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    OKOK!!!
</body>
</html>

pojo

package com.bjsxt.pojo;

import java.io.Serializable;

public class Users implements Serializable {
    private long userid;
    private String username;
    private String useremail;
    private int userage;

    public Users() {
    }

    public Users(long userid, String username, String useremail, int userage) {
        this.userid = userid;
        this.username = username;
        this.useremail = useremail;
        this.userage = userage;
    }

    public long getUserid() {
        return userid;
    }

    public void setUserid(long userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUseremail() {
        return useremail;
    }

    public void setUseremail(String useremail) {
        this.useremail = useremail;
    }

    public int getUserage() {
        return userage;
    }

    public void setUserage(int userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", useremail='" + useremail + '\'' +
                ", userage=" + userage +
                '}';
    }
}
package com.bjsxt.service;

import com.bjsxt.pojo.Users;

public interface UserService {
    void addUser(Users users);
}
package com.bjsxt.service.impl;

import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Override
    public void addUser(final Users users) {
        //设置目标队列名称,如果在配置文件中设置了目标队列名称则以这里设置的为主
        //this.jmsTemplate.setDefaultDestinationName("aaa");
        //发送消息
        this.jmsTemplate.send(new MessageCreator() {
            //通过这个方法完成消息的封装,然后回调这个方法对返回的Message做发送处理
            @Override
            public Message createMessage(Session session) throws JMSException {
                //此message为封装了users对象的message
                Message message = session.createObjectMessage(users);
                return message;
            }
        });

    }
}
package com.bjsxt.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PageController {

    @RequestMapping("/{page}")
    public String showPage(@PathVariable String page) {
        return page;
    }
}
package com.bjsxt.web.controller;

import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/addUser")
    public String addUser(Users users) {
        this.userService.addUser(users);
        return "ok";
    }
}

2 创建 spring-activemq-consumer

在这里插入图片描述

在这里插入图片描述

是一个 jar 工程

2.1 修改 POM 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.bjsxt</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>spring-activemq-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <!-- activemq客户端 -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
        </dependency>
        <!-- spring框架对JMS标准的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <!-- ActiveMQ和spring整合的插件 -->
        <dependency>
            <groupId>org.apache.xbean</groupId>
            <artifactId>xbean-spring</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
    </dependencies>


</project>

applicationContext-jms.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:jms="http://www.springframework.org/schema/jms" 
   xmlns:amq="http://activemq.apache.org/schema/core"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/jms
      http://www.springframework.org/schema/jms/spring-jms.xsd
      http://activemq.apache.org/schema/core
      http://activemq.apache.org/schema/core/activemq-core.xsd">
   <!-- 需要创建一个连接工厂,连接ActiveMQ. ActiveMQConnectionFactory. 需要依赖ActiveMQ提供的amq标签 -->
   <!-- amq:connectionFactory 是bean标签的子标签, 会在spring容器中创建一个bean对象.
      可以为对象命名. 类似: <bean id="" class="ActiveMQConnectionFactory"></bean>
    -->
   <amq:connectionFactory brokerURL="tcp://192.168.88.101:61616"
      userName="admin" password="admin" id="amqConnectionFactory"/>

   <!-- spring管理JMS相关代码的时候,必须依赖jms标签库. spring-jms提供的标签库. -->
   <!-- 定义Spring-JMS中的连接工厂对象
      CachingConnectionFactory - spring框架提供的连接工厂对象. 不能真正的访问MOM容器.
         类似一个工厂的代理对象. 需要提供一个真实工厂,实现MOM容器的连接访问.
    -->
   <bean id="connectionFactory"
      class="org.springframework.jms.connection.CachingConnectionFactory">
      <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
      <property name="sessionCacheSize" value="3"></property>
   </bean>

   
   <!-- 注册监听器 -->
   <!-- 开始注册监听. 
      需要的参数有:
         acknowledge - 消息确认机制
         container-type - 容器类型 default|simple
         simple:SimpleMessageListenerContainer最简单的消息监听器容器,只能处理固定数量的JMS会话,且不支持事务。
         default:DefaultMessageListenerContainer是一个用于异步消息监听器容器 ,且支持事务         
         destination-type - 目的地类型. 使用队列作为目的地.
         connection-factory - 连接工厂, spring-jms使用的连接工厂,必须是spring自主创建的
         不能使用三方工具创建的工程. 如: ActiveMQConnectionFactory.
    -->
   <jms:listener-container acknowledge="auto" container-type="default"
      destination-type="queue" connection-factory="connectionFactory" >
      <!-- 在监听器容器中注册某监听器对象.
         destination - 设置目的地命名
         ref - 指定监听器对象
       -->
      <jms:listener destination="test-spring" ref="myListener"/>
   </jms:listener-container>
   
</beans>

applicationContext-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
   <!-- 扫描bean对象 -->
   <context:component-scan base-package="com.bjsxt.service,com.bjsxt.listener"/>
</beans>
package com.bjsxt.listener;

import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

/**
 * 消息服务监听器
 */
@Component(value = "myListener")
public class MyMessageListener implements MessageListener {

    @Autowired
    private UserService userService;

    @Override
    public void onMessage(Message message) {
        //将消息类型转换成具体的对象类型
        ObjectMessage objectMessage = (ObjectMessage) message;
        Users users = null;
        try {
            users = (Users) objectMessage.getObject();
        } catch (JMSException e) {
            e.printStackTrace();
        }
        this.userService.showUser(users);
    }
}
package com.bjsxt.pojo;

import java.io.Serializable;

public class Users implements Serializable {
    private long userid;
    private String username;
    private String useremail;
    private int userage;

    public Users(long userid, String username, String useremail, int userage) {
        this.userid = userid;
        this.username = username;
        this.useremail = useremail;
        this.userage = userage;
    }

    public Users() {
    }

    public long getUserid() {
        return userid;
    }

    public void setUserid(long userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUseremail() {
        return useremail;
    }

    public void setUseremail(String useremail) {
        this.useremail = useremail;
    }

    public int getUserage() {
        return userage;
    }

    public void setUserage(int userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", useremail='" + useremail + '\'' +
                ", userage=" + userage +
                '}';
    }
}
package com.bjsxt.service;

import com.bjsxt.pojo.Users;

public interface UserService {
    void showUser(Users users);
}
package com.bjsxt.service.impl;

import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void showUser(Users users) {
        System.out.println(users);
    }
}
package com.bjsxt.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class TestActiveMQ {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-jms.xml","classpath:applicationContext-service.xml"});
        context.start();
        System.out.println("Spring 容器启动。。。。。。");

        //保证主线程别死掉
        System.in.read();
    }
}

BUG: 原因是缺少Jar包

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

导入jar包依赖重新运行

<!-- Spring-JMS插件相关jar包依赖 -->
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-pool</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-jms-pool</artifactId>
</dependency>

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值