activeMQ下载链接
在介绍ActiveMQ之前,首先简要介绍一下JMS规范:
JMS的基本构件
1. 连接工厂
连接工厂是客户用来创建连接的对象,例如ActiveMQ提供的ActiveMQConnectionFactory。
2.连接
JMS Connection封装了客户与JMS提供者之间的一个虚拟的连接。
3.会话
JMS Session是生产和消费消息的一个单线程上下文。会话用于创建消息生产者(producer)、消息消费者(consumer)和消息(message)等。会话提供了一个事务性的上下文,在这个上下文中,一组发送和接收被组合到了一个原子操作中。
4.目的地
目的地是客户用来指定它生产的消息的目标和它消费的消息的来源的对象。JMS1.0.2规范中定义了两种消息传递域:点对点(PTP)消息传递域和发布/订阅消息传递域。 点对点消息传递域的特点如下:
• 每个消息只能有一个消费者。
• 消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,它都可以提取消息。
发布/订阅消息传递域的特点如下:
• 每个消息可以有多个消费者。
• 生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS规范允许客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时发送的消息。
在点对点消息传递域中,目的地被成为队列(queue);在发布/订阅消息传递域中,目的地被成为主题(topic)。
- 消息生产者
消息生产者是由会话创建的一个对象,用于把消息发送到一个目的地。
6.消息消费者
消息消费者是由会话创建的一个对象,它用于接收发送到目的地的消息。消息的消费可以采用以下两种方法之一:
• 同步消费。通过调用消费者的receive方法从目的地中显式提取消息。receive方法可以一直阻塞到消息到达。
• 异步消费。客户可以为消费者注册一个消息监听器,以定义在消息到达时所采取的动作。
- 消息
JMS消息由以下三部分组成的:
• 消息头。每个消息头字段都有相应的getter和setter方法。
• 消息属性。如果需要除消息头字段以外的值,那么可以使用消息属性。
• 消息体。JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、StreamMessage和ObjectMessage。
首先我们先用代码展示不用spring管理情况下activeMQ的消息队列模式:
第一步:将下载好activeMQ解压并打开链接,如图:
浏览器输入:http://localhost:8161 输入8161管理端口是因为activemq中的jetty配置文件中默认配置端口号为8161
启动成功后:
activemq默认的用户名密码都是admin,登录成功后界面:
接下来我们就开始代码层面的编写
第二步:建一个maven工程,引入activeMQ的jar包依赖
<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.zzit.jms</groupId>
<artifactId>activemq_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
</project>
第三步:编写activemq消息的发送者:
package com.zzit.jms;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* activeMQ消息发送端
* @author yufu
*
*/
public class ActivemqSend {
private static final String url = "tcp://localhost:61616";
private static final String queueName = "myqueue";
public static void main(String[] args) {
//1.创建一个连接工厂
ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_USER,
ActiveMQConnectionFactory.DEFAULT_PASSWORD, url);
Connection conn;
Session session;
Destination destination;
MessageProducer producer;
TextMessage message;
try {
//2.创建连接
conn = factory.createConnection();
//3.启动连接
conn.start();
// 演示学习,不使用事务
//4.创建会话
session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
//5.创建一个一个目的地队列
destination = session.createQueue(queueName);
//6.创建生产者
producer = session.createProducer(destination);
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//7.创建消息
message = session.createTextMessage("发送消息" + i);
//8.发送消息
producer.send(message);
System.out.println("发送成功:" + message.getText());
}
//9.关闭连接
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
我们启动一下ActivemqSend类的main方法,让他开始发送消息:
我们记下来启动一下ActivemqReceive类的main方法,让他开始接接收消息:
观看Activemq的消息队列:
这里我们只启动了一个消费者。写完这个我们梳理一下这些接口之间的关系。
首先我们启动一个ConnectionFactory,通过ConnectionFactory来创建Connection连接,接着这通过Connection来创建会话,会话可以创建生产者MessageProducer,消费者MessageConsumer和消息TextMessage,最后生产者向队列中发送消息,消费者从队列中取消息。
下面我们说一下通过spring来整合mq的开发。
启动连接的问题我们就不再赘述了
第一步:新建maven工程,引入activemq和spring的相关依赖jar包
<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.zzit.jms</groupId>
<artifactId>activemq_spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<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.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
第二步:生产者开发:
package com.zzit.spring.activemq;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
/**
* mq和spring整合后的生产者
* @author yufu
*
*/
public class MqProducer {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private Destination destination;
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void setDestination(Destination destination) {
this.destination = destination;
}
public void sendMessage(final String message) {
jmsTemplate.send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
TextMessage msg = session.createTextMessage(message);
return msg;
}
});
System.out.println("发送的消息:" + message);
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring_producer.xml");
MqProducer mqProducer = (MqProducer) context.getBean("mqProducer");
for (int i = 0; i < 1000; i++) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mqProducer.sendMessage("消息:" + i);
}
}
}
第三步:引入生产者的spring配置文件:
<?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 http://www.springframework.org/schema/context/spring-context.xsd"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- mq为我们提供的connectionFactory -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"></property>
</bean>
<!-- spring jms提供的连接池 -->
<!-- 引入连接工厂(spring的jms为我们提供了2个connectionFactory,一个是SingleConnectionFactory,另一个是CachingConnectionFactory) -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>queue</value>
</constructor-arg>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
</bean>
<bean id="mqProducer" class="com.zzit.spring.activemq.MqProducer">
<property name="jmsTemplate" ref="jmsTemplate"></property>
<property name="destination" ref="destination"></property>
</bean>
</beans>
接下来我们就可以启动生产者,和以前的差不多,这里就不再截图了。
我们接下来看看消费者的开发,开发消费者首先需要创建消费者的监听:
package com.zzit.spring.activemq;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class ConsumerMessageListener implements MessageListener {
public void onMessage(Message message) {
TextMessage textMessage=(TextMessage) message;
try {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("接收消息:"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
消费者只要加载一下spring的配置文件就可以了。
package com.zzit.spring.activemq;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* mq和spring整合后的消费者
* @author yufu
*
*/
public class MqReceiver {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring_consumer.xml");
}
}
消费者spring配置文件的开发:
<?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 http://www.springframework.org/schema/context/spring-context.xsd"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"></property>
</bean>
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>queue</value>
</constructor-arg>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
</bean>
<!-- 配置消息容器 -->
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="destination" ref="destination"></property>
<property name="messageListener" ref="consumerMessageListener"></property>
</bean>
<!-- 消息监听器 -->
<bean id="consumerMessageListener" class="com.zzit.spring.activemq.ConsumerMessageListener"></bean>
</beans>
最后都可以在mq的消息队列中看到: