本文来自于csdn,文章通过介绍ActiveMQ的安装,使用,搭建等等,简单整理了ActiveMQ。

本文转自:http://www.uml.org.cn/zjjs/201802111.asp

一.背景介绍

1.1 java消息服务:

不同系统之间的信息交换,是我们开发中比较常见的场景,比如系统A要把数据发送给系统B,这个问题我们应该如何去处理? 1999年,原来的SUN公司领衔提出了一种面向消息的中间件服务--JMS规范(标准);常用的几种信息交互技术(httpClient、hessian、dubbo、jms、webservice 五种).

1.2 JMS概述:

JMS即Java消息服务(Java Message Service的简称),是Java EE 的标准/规范之一。这种规范(标准)指出:消息的发送应该是异步的、非阻塞的。也就是说消息的发送者发送完消息后就直接返回了,不需要等待接收者返回后才能返回,发送者和接收者可以说是互不影响。所以这种规范(标准)能够减轻或消除系统瓶颈,实现系统之间去除耦合,提高系统的整体可伸缩性和灵活性。JMS只是Java EE中定义的一组标准API,它自身并不是一个消息服务系统,它是消息传送服务的一个抽象,也就是说它定义了消息传送的接口而并没有具体实现。

1.3 ActiveMQ概述:

我们知道JMS只是消息服务的一组规范和接口,并没有具体的实现,而ActiveMQ就是JMS规范的具体实现;它是Apache下的一个项目,采用Java语言开发;是一款非常流行的开源消息服务器.

1.4 ActiveMQ与JMS关系:

我们知道,JMS只是定义了一组有关消息传送的规范和标准,并没有真正实现,也就说JMS只是定义了一组接口而已;就像JDBC抽象了关系数据库访问、JPA抽象了对象与关系数据库映射、JNDI抽象了命名目录服务访问一样,JMS具体的实现由不同的消息中间件厂商提供,比如Apache ActiveMQ就是JMS规范的具体实现,Apache ActiveMQ才是一个消息服务系统,而JMS不是。

二.ActiveMQ的使用

2.1 ActiveMQ环境搭建:

1.ActiveMQ运行需要Java的支持,首先需要配置Java环境变量;

3.切换到解压后的activemq的bin目录下 cd / usr / local / apache - activemq - 5.15.2 去启动

3.切换到bin目录下,启动:./activemq start ;关闭: . / activemq stop

4.启动后有两个端口号,一个是web控制台:8161,一个是消息服务broker连接端口:61616

5.web管理控制台admin URL地址:http : // localhost : 8161 默认登录账号 admin 密码 admin,注意:Linux防火前要关闭 ;通过这个地址可以即时访问交互信息.如下图:

消息服务broker URL地址 : tcp : // localhost : 61616

2.2 Java消息队列JMS整体设计结构

2.2.1 基本要素:1、生产者producer ; 2、消费者consumer ; 3、消息服务broker

2.2.1 交互模型:

2.2.3 JMS两种消息传送模式

点对点( Point-to-Point):专门用于使用队列Queue传送消息;基于队列Queue的点对点消息只能被一个消费者消费,如多个消费者都注册到同一个消息队列上,当生产者发送一条消息后,而只有其中一个消费者会接收到该消息,而不是所有消费者都能接收到该消息。

发布/订阅(Publish/Subscribe):专门用于使用主题Topic传送消息。基于主题的发布与订阅消息能被多个消费者消费,生产者发送的消息,所有订阅了该topic的消费者都能接收到。

2.3 Java消息队列JMS API总体概览:

2.3.1JMS API 概览

JMS API可以分为3个主要部分:

1、公共API:可用于向一个队列或主题发送消息或从其中接收消息;

2、点对点API:专门用于使用队列Queue传送消息;

3、发布/订阅API:专门用于使用主题Topic传送消息。

JMS公共API:

在JMS公共API内部,和发送与接收消息有关的JMS API接口主要是:ConnectionFactory / Connection / Session / Message / Destination / MessageProducer / MessageConsumer . 它们的关系是:一旦有了ConnectionFactory,就可以创建Connection,一旦有了Connection,就可以创建Session,而一旦有了Session,就可以创建 Message 、MessageProducer 和 MessageConsumer 。

JMS点对点API:

点对点(p2p)消息传送模型API是指JMS API之内基于队列(Queue)的接口:QueueConnectionFactory / QueueConnection / QueueSession / Message / Queue / QueueSender / QueueReceiver .

从接口的命名可以看出,大多数接口名称仅仅是在公共API接口

名称之前添加Queue一词。一般来说,使用点对点消息传送模型的应用程序将使用基于队列的API,而不使用公共API 。

JMS发布/订阅API:

发布/订阅消息传送模型API是指JMS

API之内基于主题(Topic)的接口:TopicConnectionFactory / TopicConnection /

TopicSession / Message / Topic / TopicPublisher / TopicSubscriber . 由于基于主题(Topic)的JMS API类似于基于队列(Queue)

的API,因此在大多数情况下,Queue这个词会由Topic取代。

2.4 ActiveMQ点对点发送与接收消息示例

2.4.1 简单示例:

写一个采用Queue队列方式点对点发送接收文本信息的Demo,先写发送者,如下:

package com.kinglong.activemq.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/** 
* 消息发送者 

*/ 
public class Sender {

/**消息服务器的连接地址**/ 
public static final String BROKER_URL = "tcp://192.168.174.129:61616";

public static void main(String[] args) { 
Sender sender = new Sender(); 
sender.sendMessage("Hello ActiveMQ."); 
}

/** 
* 发送消息 

* @param msg 
*/ 
public void sendMessage (String msg) {

Connection connection = null; 
Session session = null; 
MessageProducer messageProducer = null;

try { 
//1.创建一个连接工厂 
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

//2.创建一个连接 
connection = connectionFactory.createConnection();

//3.创建一个Session 
session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

//4.创建消息,此处创建了一个文本消息 
Message message = session.createTextMessage(msg);

//5.创建一个目的地 
Destination destination = session.createQueue("myQueue");

//6.创建一个消息的生产者(发送者) 
messageProducer = session.createProducer(destination);

//7.发送消息 
messageProducer.send(message);

} catch (JMSException e) { 
e.printStackTrace(); 
} finally { 
try { 
//关闭连接释放资源 
if (null != messageProducer) { 
messageProducer.close(); 

if (null != session) { 
session.close(); 

if (null != connection) { 
connection.close(); 

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



}

再写接收者:

package com.kinglong.activemq.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class Receiver {

/**消息服务器的连接地址**/ 
public static final String BROKER_URL = "tcp://192.168.174.129:61616";

public static void main(String[] args) { 
Receiver receiver = new Receiver(); 
receiver.receiveMessage(); 
}

/** 
* 接收消息 

*/ 
public void receiveMessage () {

Connection connection = null; 
Session session = null; 
MessageConsumer messageConsumer = null;

try { 
//1.创建一个连接工厂 
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

//2.创建一个连接 
connection = connectionFactory.createConnection();

//3.创建一个Session 
session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

//4.创建一个目的地 
Destination destination = session.createQueue("myQueue");

//5.创建一个消息的消费者(接收者) 
messageConsumer = session.createConsumer(destination);

//接收消息之前,需要把连接启动一下 
connection.start();

//6.接收消息 
Message message = messageConsumer.receive();

//判断消息的类型 
if (message instanceof TextMessage) { //判断是否是文本消息 
String text = ((TextMessage) message).getText(); 
System.out.println("接收到的消息内容是:" + text); 

} catch (JMSException e) { 
e.printStackTrace(); 
} finally { 
try { 
//关闭连接释放资源 
if (null != messageConsumer) { 
messageConsumer.close(); 

if (null != session) { 
session.close(); 

if (null != connection) { 
connection.close(); 

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



}

总结:

创建过程中有几个重要的注意点,说明一下:

1. session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); 
// 其中:Boolean.FALSE表示本次会话不开启事务管理,假如需要开启事务管理,将其改为Boolean.TRUE即可 
//同时需要在发送消息后添加session.commit(),否则,消息是不会被提交的. 
//Session.AUTO_ACKNOWLEDGE表示消息确认机制 
AUTO_ACKNOWLEDGE:自动确认 
CLIENT_ACKNOWLEDGE:客户端确认 
SESSION_TRANSACTED:事务确认,如果使用事务推荐使用该确认机制 
AUTO_ACKNOWLEDGE:懒散式确认,消息偶尔不会被确认,也就是消息可能会被重复发送.但发生的概率很小 
2. connection.start(); 
//在消息接收端,接受消息前需要加入这段代码,开启连接,否则一样无法获取消息. 
3. Destination destination = session.createQueue("myQueue"); 
//创建目的地时,如果做测试收不到信息,可以将目的地名称修改一下,我用的是IDEA,不清楚为何, 
//有时候收不到信息,修改一下就好了,猜测可能是缓存的原因吧

发布与订阅的topic方式实际与点对点的queue方式,代码通用很多,只是在创建目的地Destination时候创建为

Destination destination = session.createTopic("myTopic

2.4.2Queue与Topic比较

2.4.3拉模式与推模式

a.点对点消息,如果没有消费者在监听队列,消息将保留在队列中,直至消息消费者连接到队列为止。这种消息传递模型是

传统意义上的懒模型或轮询模型。在此模型中,消息不是自动推动给消息消费者的,而是要由消息消费者从队列中请求获得(拉模式)。

b.pub/sub消息传递模型基本上是一个推模型。在该模型中,消息会自动广播,消息消费者无须通过主动请求或轮询主题的方法来获得新的消息。

2.5 ActiveMQ消息类型

1、TextMessage 文本消息:携带一个java.lang.String作为有效数据(负载)的消息,可用于字符串类型的信息交换;

2、ObjectMessage 对象消息:携带一个可以序列化的Java对象作为有效负载的消息,可用于Java对象类型的信息交换;

3、MapMessage 映射消息:携带一组键值对的数据作为有效负载的消息,有效数据值必须是Java原始数据类型(或者它们的包装类)及String。即:byte , short , int , long , float , double , char , boolean , String

4、BytesMessage 字节消息 :携带一组原始数据类型的字节流作为有效负载的消息;

5、StreamMessage 流消息:携带一个原始数据类型流作为有效负载的消息,它保持了写入流时的数据类型,写入什么类型,

则读取也需要是相同的类型;

需要注意的是:如果使用对象消息做Demo时,如果使用之前的连接创建方式可能会无法接收到消息,因为安全问题.所以,如果想要使用Demo测试对象消息,创建连接时建议改为这样(官网推荐的连接方式):

//创建对象消息连接工厂 
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(BROKER_URL); 
List<String > list = new ArrayList<String>(); 
list.add("com.kinglong.activemq.receiver"); 
list.add("com.kinglong.activemq.model"); 
activeMQConnectionFactory.setTrustedPackages(list);

2.6 ActiveMQ事务消息和非事务消息

消息分为事务消息和非事务消息

1、事务消息:创建会话Session使用transacted=true

connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

2、非事务消息:创建会话Session使用transacted=false

connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

事务消息必须在发送和接收完消息后显式地调用session.commit();

事务性消息,不管设置何种消息确认模式,都会自动被确认;与设置的确认机制无关,但官方推荐事务性消息使用事务确认机制.

2.7 ActiveMQ消息确认机制

消息只有在被确认之后,才认为已经被成功消费,然后消息才会从队列或主题中删除。消息的成功消费通常包含三个阶段:

(1)、客户接收消息;(2)、客户处理消息;(3)、消息被确认;

确认机制前面提过一下,共有四种:

(1)、Session.AUTO_ACKNOWLEDGE;客户(消费者)成功从receive方法返回时,或者从MessageListener.onMessage方法成功返回时,会话自动确认消息,然后自动删除消息.

(2)、Session.CLIENT_ACKNOWLEDGE;客户通过显式调用消息的acknowledge方法确认消息,。 即在接收端调用message.acknowledge();方法,否则,消息是不会被删除的.

(3)、Session. DUPS_OK_ACKNOWLEDGE ;不是必须确认,是一种“懒散的”消息确认,消息可能会重复发送,在第二次重新传送消息时,消息头的JMSRedelivered会被置为true标识当前消息已经传送过一次,客户端需要进行消息的重复处理控制。

(4)、 Session.SESSION_TRANSACTED;事务提交并确认。

2.8 ActiveMQ持久化消息与非持久化消息

messageProducer.setDeliveryMode(DeliveryMode. NON_PERSISTENT);//不持久化
messageProducer.setDeliveryMode(DeliveryMode.

PERSISTENT);//持久化的,当然activemq发送消息默认都是持久化的

说明:

设置完后,如果为持久化,那么消息在没有被消费前都会被写入本地磁盘kahadb文件中保存起来,即使服务器宕机,也不会影响

消息.如果是非持久化的,那么,服务一旦宕机之类的情况发生,消息即会被删除.

ActiveMQ默认是持久化的.

2.9 ActiveMQ消息过滤

ActiveMQ提供了一种机制,可根据消息选择器中的标准来执行消息过滤,只接收符合过滤标准的消息;

生产者可在消息中放入特有的标志,而消费者使用基于这些特定的标志来接收消息;

1、发送消息放入特殊标志:message . setString Property ( name , value ) ;

2、接收消息使用基于特殊标志的消息选择器:

MessageConsumer createConsumer(Destination destination, String messageSelector);

注:消息选择器是一个字符串,语法与数据库的SQL相似,相当于SQL语句where条件后面的内容;

具体代码如下:

发送端代码:

package com.bjpowernode.activemq.selector;

import org.apache.activemq.Active

MQConnectionFactory;

import javax.jms.*;

/** 
* 消息发送者 

*/ 
public class Sender {

/**消息服务器的连接地址**/ 
public static final String BROKER_URL = "tcp://192.168.174.129:61616";

public static void main(String[] args) { 
Sender sender = new Sender(); 
sender.sendMessage("Hello ActiveMQ."); 
}

/** 
* 发送消息 

* @param msg 
*/ 
public void sendMessage (String msg) {

Connection connection = null; 
Session session = null; 
MessageProducer messageProducer = null;

try { 
//1.创建一个连接工厂 
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

//2.创建一个连接 
connection = connectionFactory.

createConnection();

//3.创建一个Session 
session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

//5.创建一个目的地 
Destination destination = session.create

Queue("myQueue");

//6.创建一个消息的生产者(发送者) 
messageProducer = session.createProducer

(destination);

//设置发送的消息是否需要持久化 
messageProducer.setDeliveryMode(Delivery

Mode.NON_PERSISTENT);//这里使用不持久化

//创建一个循环,测试消息标识的使用 
for (int i=0; i<20; i++) { 
//4.创建消息,此处创建了一个文本消息 
Message message = session.createText

Message(msg+i);

//将消息设置一个特有的标识 
message.setIntProperty("id", i);

//7.发送消息 
messageProducer.send(message); 

} catch (JMSException e) { 
e.printStackTrace(); 
} finally { 
try { 
//关闭连接释放资源 
if (null != messageProducer) { 
messageProducer.close(); 

if (null != session) { 
session.close(); 

if (null != connection) { 
connection.close(); 

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



}

接收端代码:

package com.bjpowernode.activemq.selector;

import org.apache.activemq.ActiveMQ

ConnectionFactory;

import javax.jms.*;

public class Receiver {

/**消息服务器的连接地址**/ 
public static final String BROKER_URL = "tcp://192.168.174.129:61616";

public static void main(String[] args) { 
Receiver receiver = new Receiver(); 
receiver.receiveMessage(); 
}

/** 
* 接收消息 

*/ 
public void receiveMessage () {

Connection connection = null; 
Session session = null; 
MessageConsumer messageConsumer = null;

try { 
//1.创建一个连接工厂 
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

//2.创建一个连接 
connection = connectionFactory.

createConnection();

//3.创建一个Session 
session = connection.createSession

(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

//4.创建一个目的地 
Destination destination = session.createQueue("myQueue");

//5.创建一个消息的消费者(接收者),

selector即为消息选择器,通过选择需要的标识,过滤消息接受id为10-15之 //间的消息 
String selector = "id >=10 and id<=15"; 
messageConsumer = session.createConsumer

(destination, selector);

//接收消息之前,需要把连接启动一下 
connection.start();

while (true) { 
//6.接收消息 同步接收 
Message message = messageConsumer.

receive();

//判断消息的类型 
if (message instanceof TextMessage)

{ //判断是否是文本消息 
String text = ((TextMessage) message).getText(); 
System.out.println("接收到的消息内容是:" + text); 


} catch (JMSException e) { 
e.printStackTrace(); 
} finally { 
try { 
//关闭连接释放资源 
if (null != messageConsumer) { 
messageConsumer.close(); 

if (null != session) { 
session.close(); 

if (null != connection) { 
connection.close(); 

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



}

2.10 ActiveMQ消息接收方式

同步接收:receive()方法接收消息叫同步接收,就是之前的Demo代码使用的接收方式.在不使用循环方法时接收端代码执行

一次即结束.

异步接收:使用监听器接收消息,这种接收方式叫异步接收,接收端会一直处于监听状态,只要有消息产生,即会接收消息.

下面是异步接收代码:

package com.bjpowernode.activemq.listener;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class Receiver {

/**消息服务器的连接地址**/ 
public static final String BROKER_URL = "tcp://192.168.174.129:61616";

public static void main(String[] args) { 
Receiver receiver = new Receiver(); 
receiver.receiveMessage(); 
}

/** 
* 接收消息 

*/ 
public void receiveMessage () {

Connection connection = null; 
Session session = null; 
MessageConsumer messageConsumer = null;

try { 
//1.创建一个连接工厂 
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

//2.创建一个连接 
connection = connectionFactory.createConnection();

//3.创建一个Session 
session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

//4.创建一个目的地 
Destination destination = session.createQueue("myQueue");

//5.创建一个消息的消费者(接收者) 
messageConsumer = session.createConsumer(destination);

//接收消息之前,需要把连接启动一下 
connection.start();

//6.接收消息 同步接收 
//Message message = messageConsumer.receive();

//异步接收,使用监听器接收消息 
messageConsumer.setMessageListener(new MessageListener(){ 
public void onMessage(Message message) { 
//判断消息的类型 
if (message instanceof TextMessage) { //判断是否是文本消息 
String text = null; 
try { 
text = ((TextMessage) message).getText(); 
} catch (JMSException e) { 
e.printStackTrace(); 

System.out.println("接收到的消息内容是:" + text); 


}); 
} catch (JMSException e) { 
e.printStackTrace(); 
} finally { 
/*try { 
//关闭连接释放资源 
if (null != messageConsumer) { 
messageConsumer.close(); 

if (null != session) { 
session.close(); 

if (null != connection) { 
connection.close(); 

} catch (JMSException e) { 
e.printStackTrace(); 
}*/ 


}

三.ActiveMQ的集成使用:

3.1ActiveMQ与Spring集成(以下是一个简单的上手Demo):

鉴于发送端与接收端pom文件依赖相同,所以只写一份,依赖如下:

[html] view plain copy
<!--spring-jms依赖--> 
<dependency> 
<groupId>org.springframework</groupId> 
<artifactId>spring-jms</artifactId> 
<version>4.3.13.RELEASE</version> 
</dependency>

<!--activemq的jar依赖--> 
<dependency> 
<groupId>org.apache.activemq</groupId> 
<artifactId>activemq-client</artifactId> 
<version>5.15.2</version> 
</dependency>

<!-- JMS规范的jar依赖 --> 
<dependency> 
<groupId>javax.jms</groupId> 
<artifactId>javax.jms-api</artifactId> 
<version>2.0.1</version> 
</dependency>

发送端:(需要两个配置文件)

1. applicationContext.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" 
xsi:schemaLocation="http://www.springframework.

org/schema/beans http://www.springframework.

org/schema/beans

/spring-beans.xsd">

<import resource="applicationContext-jms.xml"/>

</beans>

2. 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:context="http://www.springframework.org/

schema/context" 
xsi:schemaLocation="http://www.springframework.

org/schema/beans http://www.springframework.

org/schema/beans/

spring-beans.xsd http://www.springframework.

org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.kinglong.activemq.sender"/>

<!-- 配置一个连接工厂 --> 
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnection

Factory"> 
<property name="brokerURL" value="tcp://192.168.

174.129:61616"/> 
</bean>

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

Factory" /> 
<property name="defaultDestinationName"

value="springTopic" /> 
<!--指定消息传送模式,true表示发布订阅、

false表示点对点--> 
<property name="pubSubDomain" value="true"/> 
</bean>

</beans>

发送类:

package com.kinglong.activemq.sender;

import org.springframework.beans.factory.annotation

.Autowired; 
import org.springframework.jms.core.

JmsTemplate; 
import org.springframework.jms.core.

MessageCreator; 
import org.springframework.stereotype.Component;

import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.Session; 
@Component 
public class Sender {

@Autowired 
private JmsTemplate jmsTemplate;

public void sendMessage (final String msg) { 
//发送消息 
jmsTemplate.send(new MessageCreator() { 
public Message createMessage(Session

session) throws JMSException { 
return session.createTextMessage(msg); 

}); 
}

}

下面是测试类:

package com.kinglong.activemq.sender;

import org.springframework.context.support.

ClassPathXmlApplicationContext;

public class Test { 
public static void main(String[] args) {

ClassPathXmlApplicationContext context = 
new ClassPathXmlApplicationContext("classpath:app

licationContext.xml");

Sender springSender = (Sender)context.getBean("sender");

springSender.sendMessage("Spring jms ActiveMQ.");


}

接收端(也同样需要两个配置文件,这里使用异步接收,所以需要配置一个监听器):

1. applicationContext.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" 
xsi:schemaLocation="http://www.springframework.

org/schema/beans http://www.springframework.

org/schema

/beans/spring-beans.xsd">

<import resource="applicationContext-jms.xml"/>

</beans>

2. applicationContext-jms.xml

监听器:(MyMessageListener)

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org

/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XML

Schema-instance" 
xmlns:context="http://www.springframework.

org/schema/context" 
xsi:schemaLocation="http://www.springframework.

org/schema/beans http://www.springframework.

org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context

/spring-context.xsd">

<context:component-scan base-package="com

.kinglong.activemq.receiver"/>

<!-- 配置一个连接工厂 --> 
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 
<property name="brokerURL" value="tcp://192.

168.174.129:61616"/> 
</bean>

<!-- 配置JmsTemplate --> 
<bean id="jmsTemplate" class="org.springframework.

jms.core.JmsTemplate"> 
<property name="connectionFactory" ref="

connectionFactory" /> 
<property name="defaultDestinationName"

value="springTopic" /> 
<!--指定消息传送模式,true表示发布订阅、

false表示点对点--> 
<property name="pubSubDomain" value="true"/> 
</bean>

<!-- 我们自定义的一个消息监听器 --> 
<bean id="receiverListener" class="com.kinglong.activemq.receiver.MyMessage

Listener" />

<!-- 配置一个sping监听器的容器 --> 
<bean class="org.springframework.jms.listener.Default

MessageListenerContainer"> 
<property name="connectionFactory" ref="

connectionFactory"/> 
<property name="destinationName" value="

springTopic"/> 
<property name="messageListener" ref="receiver

Listener" /> 
<!--指定消息传送模式,true表示发布订阅、

false表示点对点--> 
<property name="pubSubDomain" value="true"/> 
</bean>

</beans>

下面是测试类:

package com.kinglong.activemq.receiver;

import org.springframework.context.support.Class

PathXmlApplicationContext;

public class Test {

public static void main(String[] args) {

ClassPathXmlApplicationContext context = 
new ClassPathXmlApplicationContext("classpath:

applicationContext.xml");

}

}

说明:由于使用的是Topic发布订阅模式,所以测试时一定先开启接收端服务,再开启发送端发送消息,否则接不到消息.

相比较之下,spring集成的activemq使用已经相当简化,与原始版相比,整个链接对象的创建全部交给spring完成了,所以效率上更高了.

其次,各属性配置也都从代码中剥离归整在配置文件里,使得修改配置也变得更为容易,但是,个人觉得还是有必要学习学习原始版本,

可以更好地理解其创建过程,加深理解.

3.2ActiveMQ与Springboot集成(以下是一个简单的上手Demo):

同样pom依赖,因为依赖相同,所以只写一份,如下:

<!--配置父级依赖--> 
<parent> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-starter-parent</artifactId> 
<version>1.5.9.RELEASE</version> 
<relativePath/> <!-- lookup parent from repository --> 
</parent>

<!--属性配置--> 
<properties> 
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
<java.version>1.8</java.version> 
</properties>

<dependencies>

<!--开发springboot的Java程序的起步依赖--> 
<dependency> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-starter</artifactId> 
</dependency>

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

<!--springboot集成activemq的起步依赖--> 
<dependency> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-starter-activemq</artifactId> 
</dependency>

</dependencies>

发送端:

只有一个主配置文件:application.properties

spring.activemq.broker-url=tcp://192.168.174.129:61616

#发布订阅模式 
spring.jms.pub-sub-domain=true

main方法类:

package com.kinglong.activemq;

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.

SpringBootApplication; 
import org.springframework.context.Configurable

ApplicationContext;

@SpringBootApplication 
public class SenderApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SenderApplication.

class, args);

SpringBootSender springBootSender = (SpringBootSender)context.getBean

("springBootSender");

springBootSender.sendMessage("springboot

activemq."); 
}

}

发送者:SpringBootSender

package com.kinglong.activemq;

import org.springframework.beans.factory.

annotation.Autowired; 
import org.springframework.jms.core.JmsTemplate; 
import org.springframework.jms.core.MessageCreator; 
import org.springframework.stereotype.Component;

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

@Component 
public class SpringBootSender {

@Autowired //注入JmsTemplate 
private JmsTemplate jmsTemplate;

//发送消息,"myTopic"是发送到的队列

destination,message是待发送的消息 
public void sendMessage(String message) { 
jmsTemplate.send("myTopic", new Message

Creator() { 
@Override 
public Message createMessage(Session session)

throws JMSException { 
return session.createTextMessage(message); 

}); 

}

接收端:

主配置文件与发送端相同

main方法类:ReceiverApplication

package com.kinglong.activemq;

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.

SpringBootApplication; 
import org.springframework.context.Configurable

ApplicationContext;

import javax.jms.JMSException;

@SpringBootApplication 
public class ReceiverApplication {

public static void main(String[] args) throws

JMSException {

ConfigurableApplicationContext context = SpringApplication.run(ReceiverApplication.

class, args);

//这里采用异步接收


}

监听器:MessageListenerReceiver

package com.kinglong.activemq;

import org.springframework.jms.annotation.JmsListener; 
import org.springframework.stereotype.Component;

@Component 
public class MessageListenerReceiver {

@JmsListener(destination = "myTopic") 
public void receiveQueue(String text) { 
System.out.println("Consumer收到的报文为:" + text); 

}

OVER! 是不是发现springboot集成的ActiveMQ更加精巧了?配置文件都不用写了,springboot全帮我们做完了.不过,还是那句话,建议把原始版本原理,思路整通了再做spring或是springboot的集成,要不感觉直接理解起来springboot的发送和接收还是比较抽象的.

四.ActiveMQ集群

4.1 何为集群?

集群就是将相同的程序、功能,部署在两台或多台服务器上,这些服务器对外提供的功能是完全一样的。通过不断横向扩展增加服务器的方式,以提高服务的能力。

4.1.1 不集群模式

4.1.2 集群模式

4.2 集群的优势:

1、集群可以解决单点故障问题;

2、集群可以提高系统服务能力;

ActiveMQ---知识点整理的更多相关文章

  1. ACM个人零散知识点整理

    ACM个人零散知识点整理 杂项: 1.输入输出外挂 //读入优化 int 整数 inline int read(){ int x=0,f=1; char ch=getchar(); while(ch& ...

  2. Android 零散知识点整理

    Android 零散知识点整理 为什么Android的更新试图操作必须在主线程中进行? 这是因为Android系统中的视图组件并不是线程安全的.通常应该让主线程负责创建.显示和更新UI,启动子线程,停 ...

  3. vue前端面试题知识点整理

    vue前端面试题知识点整理 1. 说一下Vue的双向绑定数据的原理 vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫 ...

  4. kafka知识点整理总结

    kafka知识点整理总结 只不过是敷衍 2017-11-22 21:39:59 kafka知识点整理总结,以备不时之需. 为什么要使用消息系统: 解耦 并行 异步通信:想向队列中放入多少消息就放多少, ...

  5. JSP页面开发知识点整理

    刚学JSP页面开发,把知识点整理一下. ----------------------------------------------------------------------- JSP语法htt ...

  6. JS知识点整理(二)

    前言 这是对平时的一些读书笔记和理解进行整理的第二部分,第一部分请前往:JS知识点整理(一).本文包含一些易混淆.遗漏的知识点,也会配上一些例子,也许不是很完整,也许还会有点杂,但也许会有你需要的,后 ...

  7. css入门知识点整理

    css入门知识点整理 不要嘲笑我这个蒟蒻..例子来源:w3school css其实就分为两个东西,一个是选择器,另外一个是声明.声明定义了某个对象的属性的值,这都是html的内容.重点要关注的是选择器 ...

  8. activity生命周期知识点整理

    activity生命周期知识点整理 Activity: 是一个应用组件,用户可与其提供的屏幕进行交互.窗口通常会充满屏幕,但也可以小于屏幕并浮动在其他窗口之上. 一个activity的什么周期: 启动 ...

  9. 【Android 面试基础知识点整理】

    针对Android面试中常见的一些知识点整理,Max 仅仅是个搬运工.感谢本文中引用文章的各位作者,给大家分享了这么多优秀文章.对于当中的解析,是原作者个人见解,有错误和不准确的地方,也请大家积极指正 ...

  10. 2019.10.15 CSP初赛知识点整理

    初赛需要的知识点整理如下: (1)计算机的硬件组成与基本常识 (2)单位/进制的转换 (3)进制/逻辑运算相关 (4)概率与期望 (5)排序的各种性质 (6)简单数据结构的使用(栈.队列.链表等) ( ...

随机推荐

  1. Linux系统下tomcat安装配置

    Linux系统中Tomcat的安装配置. 前提JDK已经安装好. 安装 下载tomcatwget http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.0 ...

  2. ajax初级知识(转载)

    1.什么是ajax? Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写. 2.ajax需要什么基础? HTML 用于建立 Web 表单并确定应 ...

  3. PHP获取目录和的方法通过魔术变量;通过超级全局变量;通过相关函数等等:

    <?php /** * PHP获取路径或目录实现 * @link http://www.phpddt.com */ //魔术变量,获取当前文件的绝对路径 echo "__FILE__: ...

  4. POI官网中的例子

    官方指南中的例子: http://poi.apache.org/spreadsheet/quick-guide.html#New+Sheet 这一节 Workbook wb = new HSSFWor ...

  5. Python大数据:jieba 中文分词,词频统计

    # -*- coding: UTF-8 -*- import sys import numpy as np import pandas as pd import jieba import jieba. ...

  6. Drawing Graphs using Dot and Graphviz

    Drawing Graphs using Dot and Graphviz Table of Contents 1. License 2. Introduction 2.1. What is DOT? ...

  7. Day27-28 基础加强

    day28基础加强 今日内容 泛型 注解 Servlet3.0 动态代理 类加载器   泛型 回顾泛型类 泛型类:具有一个或多个泛型变量的类被称之为泛型类. public class A<T&g ...

  8. Python 之各种推导式玩法

    推导式套路 之前我们已经学习了最简单的列表推导式和生成器表达式.但是除此之外,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. variable ...

  9. 1.2、Django 视图与网址__进阶

    Django 视图与网址进阶 1.1.简单使用: 把我们新定义的app加到settings.py中的INSTALL_APPS中 修改 HelloDjango/HelloDjango/settings. ...

  10. #C++初学记录(并查集)

    并查集 题目 今天是伊格那丢的生日.他邀请了很多朋友.现在该吃晚饭了.伊格那丢想知道他至少需要多少张桌子.你必须注意到并不是所有的朋友都认识对方,而且所有的朋友都不想和陌生人待在一起.这个问题的一个重 ...