ActiveMQ 03 ActiveMQ基础

1、安装ActiveMQ

⑴ 下载apache-activemq-5.15.1-bin.tar.gz

⑵ 解压缩

⑶ 到bin目录下启动和关闭
启动命令:./activemq start
关闭命令:./activemq stop

2、管理ActiveMQ

默认端口为8161,用户名和密码都为admin

3、队列模式

⑴ 特点

① 一个消息只能被一个消费者所消费
② 消费者可以随时消费消息

⑵ API

① ConnectionFactory

连接工厂

实现类:ActiveMQConnectionFactory
public ActiveMQConnectionFactory(String brokerURL) {}
需要传入ActiveMQ服务器的连接地址,端口默认为61616

② Connection

连接,由连接工厂所创建。通过连接可以创建会话(Session)
Connection createConnection() throws JMSException;

void start() throws JMSException;
打开连接。很重要

void close() throws JMSException;
关闭连接

③ Session

会话,可以创建目的地(Destination)、生产者(MessageProducer)和消费者(MessageConsumer)

Session createSession(boolean var1, int var2) throws JMSException;
第一个参数为是否开启事务,第二个参数为

      可以选择Session的常量:
        int AUTO_ACKNOWLEDGE = 1;
        int CLIENT_ACKNOWLEDGE = 2;
        int DUPS_OK_ACKNOWLEDGE = 3;
        int SESSION_TRANSACTED = 0;

MessageProducer createProducer(Destination var1) throws JMSException;
传入目的地

MessageConsumer createConsumer(Destination var1) throws JMSException;
传入目的地

④ Queue

队列,由Session创建
Queue createQueue(String var1) throws JMSException;
传入队列的名称

public interface Queue extends Destination {}
Destination就是目的地

⑤ TextMessage

文本类型的消息,由Session创建
TextMessage createTextMessage(String var1) throws JMSException;
需要传入消息的内容

⑥ send

void send(Message var1) throws JMSException;
发送消息,由MessageProducer调用

⑦ setMessageListener

void setMessageListener(MessageListener var1) throws JMSException;
传入一个消息监听器

  public interface MessageListener {
      void onMessage(Message var1);
  }

可以将Message对象强转为具体的消息对象,再调用具体的方法获取消息内容
例如:

  public interface TextMessage extends Message {
      String getText() throws JMSException;
  }

可以获得文本消息类型的消息内容

⑶ 示例

private static final String brokerURL = ???;
private static final String QUEUE_NAME = ???;

【生产者】

    ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
    Connection connection = connectionFactory.createConnection();
    connection.start(); // 启动连接
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createQueue(QUEUE_NAME);
    MessageProducer producter = session.createProducer(destination);

    for (int i = 1; i <= 100; i++) {
        TextMessage textMessage = session.createTextMessage("queue-message-" + i);
        producter.send(textMessage);
        System.out.println("发送消息" + textMessage.getText());
    }
    producter.close();
    connection.close();

【消费者】

    ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
    Connection connection = connectionFactory.createConnection();
    connection.start(); // 启动连接
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createQueue(QUEUE_NAME);
    MessageConsumer consumer = session.createConsumer(destination);

    consumer.setMessageListener(new MessageListener() {
        @Override
        public void onMessage(Message message) {
            TextMessage textMessage = (TextMessage) message;
            try {
                System.out.println(textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    });

注意消费者和连接都不能关闭,否则无法异步获取消息

4、主题模式

⑴ 特点

① 所有的消息都能被订阅者所消费
② 订阅者只能消费它所订阅的消息,订阅前的消息并不能被其消费

⑵ API

Topic createTopic(String var1) throws JMSException;
创建主题,由Session创建,需要传入主题的名称

⑶ 示例

private static final String brokerURL = "";
private static final String TOPIC_NAME = "";

【发布者】

    ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
    Connection connection = null;
    try {
        connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createTopic(TOPIC_NAME);
        MessageProducer messageProducer = session.createProducer(destination);
        for (int i = 1; i <= 100; i++) {
            TextMessage message = session.createTextMessage("topic-message-" + i);
            messageProducer.send(message);
            System.out.println(message.getText());
        }
    } catch (JMSException e) {
        e.printStackTrace();
    } finally {
        if (null != connection) {
            try {
                connection.close();
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }

【订阅者】

    ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
    Connection connection = connectionFactory.createConnection();
    connection.start();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createTopic(TOPIC_NAME);
    MessageConsumer consumer = session.createConsumer(destination);
    consumer.setMessageListener((message) -> {
        TextMessage textMessage = (TextMessage) message;
        try {
            System.out.println("接收消息:" + textMessage.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    });

注意订阅者和连接都不能关闭,否则无法异步获取消息

5、整合Spring

⑴ pom依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-core</artifactId>
        <version>${activemq.version}</version>
        <!-- 排除ActiveMQ自身的Spring-Context的依赖 -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

⑵ API

① SingleConnectionFactory

由Spring-Jms提供的整合消息中间件的连接工厂(连接池)。它有一个ConnectionFactory targetConnectionFactory的属性,用于指定目标连接工厂,可以引用ActiveMQConnectionFactory

② CachingConnectionFactory

继承自SingleConnectionFactory,它可以缓存会话(Session),当然也包括生产者和消费者

③ ActiveMQQueue

由ActiveMQ提供的队列。需要指定消息的name属性,可以通过set注入或者构造注入

④ ActiveMQTopic

由ActiveMQ提供的主题。需要指定消息的physicalName,可以通过set注入或者构造注入

⑤ JmsTemplate

用于发送和接收消息的模版类。需要指定connectionFactory属性,可以set注入或者构造注入
它每次发送消息时,都会重新创建连接、会话和生产者
同时它也是线程安全的,可以在整个应用中使用它

⑥ MessageListener

消息监听器。接口,消费者可以实现它,并实现
void onMessage(Message message);方法,通过将Message对象强转为相应的消息对象,并获取对应的消息

⑦ DefaultMessageListenerContainer

消息监听容器。需要指定connectionFactory,destination以及messageListener

⑶ 示例

由于生产者和消费者都需要配置连接池、连接工厂、消息,所以可以将这些提取出来,再通过import引用即可复用

【common.xml】

<!-- 启用注解 -->
<context:annotation-config />
<!-- 引入配置文件 -->
<context:property-placeholder location="classpath:activemq.properties" />

<!-- ActiveMQ -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="${activemq.brokerUrl}" />
</bean>
<!-- 连接池 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="activeMQConnectionFactory" />
</bean>

<!-- Queue队列 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg value="${activemq.queueName}" />
</bean>
<!-- Topic主题 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
    <property name="physicalName" value="${activemq.topicName}" />
</bean>

【producer.xml】

<import resource="classpath:common.xml" />

<!-- JmsTemplate -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
</bean>

<!-- 生产者实现类 -->
<bean class="???" />

【consumer.xml】

<import resource="classpath:common.xml" />

<!-- 消息监听器实现类 -->
<bean id="messageListener" class="???" />
<!-- 消息监听容器 -->
<bean id="messageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory" />
    <!-- 引入队列【仅能选择一个】 -->
    <property name="destination" ref="queueDestination" />
    <!-- 引入主题【仅能选择一个】 -->
    <property name="destination" ref="topicDestination" />
    <property name="messageListener" ref="messageListener" />
</bean>

【生产者接口】

public interface Producer {
    void sendMessage(String message);
}

【生产者实现类】

public class Producer implements Producer {
    @Autowired
    private JmsTemplate jmsTemplate;

    @Resource(name = "消息的id属性,队列或主题")
    private Destination destination;

    @Override
    public void sendMessage(String name) {
        jmsTemplate.send(destination, new MessageCreator(Session session) throws JMSException {
            return session.createTextMessage(name);
        });
    }

}

【消费者】

public class Consumer implements MessageListener {

    @Override
    public void onMessage(Message message) {
        TextMessage textMessage = (TextMessage) message;
        try {
            System.out.println("接收消息" + textMessage.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

}

队列模式和主题模式的切换在于生产者/发布者通过@Resource所引用的消息,以及消息模式的配置和消息监听器容器所引用的消息模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值