对于消息的传递有两种类型
1.一种是点对点的,即一个生产者和一个消费者一一对应(生产者将消息发出以后,消费者未接受时会将消息缓存在服务端,等待消费则登陆)
2.另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。(服务端不缓存消息)
消息正文格式(JMS定义)
· StreamMessage -- Java原始值的数据流
· MapMessage--一套名称-值对
· TextMessage--一个字符串对象
· ObjectMessage--一个序列化的 Java对象
· BytesMessage--一个字节的数据流
JMS应用程序接口
ConnectionFactory 接口(连接工厂)
Connection 接口(连接)
Destination 接口(目标)
目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点
MessageConsumer 接口(消息消费者)
由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息
MessageProducer 接口(消息生产者)
由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
Message 接口(消息)
Session 接口(会话)
表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的
例子(整合Spring maven管理):
则添加jar包的依赖:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.11.2</version>
</dependency>
消息发送
配置ConnectionFactory(发送接受一样)
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.168:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
配置消息的Destination对象(发送接受一样)
<!--这个是队列目的地,点对点的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="queue"></constructor-arg>
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="topic"></constructor-arg>
</bean>
配置JMSTemplate(发送配置)
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
发送代码(例子)
public class ItemServiceImpl implements ItemService {
@Autowired
private JmsTemplate jmsTemplate;
//可以根据需求注入不同的(quere或topic)
@Resource(name = "itemAddtopic")
private Destination destination;
@Override
public TaotaoResult addItem(TbItem item, String desc, String itemParam) {
// 向Activemq发送商品添加消息
jmsTemplate.send(destination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
// 发送商品id
TextMessage textMessage = session.createTextMessage(id + "");
return textMessage;
}
});
return TaotaoResult.ok();
}
}
接受消息
配置ConnectionFactory(发送接受一样)
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.168:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
配置消息的Destination对象(发送接受一样)
<!--这个是队列目的地,点对点的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="queue"></constructor-arg><!-- value要和需要接受的消息目标名一致 -->
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="topic"></constructor-arg><!-- value要和需要接受的消息目标名一致 -->
</bean>
配置西消息接受
<!-- queue配置消息的接收拦截器 -->
<bean id="queueListener" class="com.cs.item.listener.QueueListener"/>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueDestination" />
<property name="messageListener" ref="queueListener" />
</bean>
<!-- topic配置消息的接收拦截器 -->
<bean id="topicListener" class="com.cs.item.listener.TopicListener"/>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicDestination" />
<property name="messageListener" ref="topicListener" />
</bean>
拦截器(消息接受中配的拦截器)
queue(点对点拦截器)
package com.cs.item.listener;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import javax.xml.soap.Text;
/**
* 接收Activemq发送的消息
* <p>Title: MyMessageListener</p>
* <p>Description: </p>
* <p>Company: www.itcast.cn</p>
* @version 1.0
*/
public class QueueListener implements MessageListener {
@Override
public void onMessage(Message message) {
try {
//接收到消息
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
System.out.println(text);
} catch (Exception e) {
e.printStackTrace();
}
}
}
topic(点对面拦截器)
package com.cs.item.listener;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import javax.xml.soap.Text;
/**
* 接收Activemq发送的消息
* <p>Title: MyMessageListener</p>
* <p>Description: </p>
* <p>Company: www.itcast.cn</p>
* @version 1.0
*/
public class TopicListener implements MessageListener {
@Override
public void onMessage(Message message) {
try {
//接收到消息
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
System.out.println(text);
} catch (Exception e) {
e.printStackTrace();
}
}
}