一. 介绍

  借助Spring,有多种异步消息的可选方案,本章使用Jms。Jms的消息模型有两种,点对点消息模型(队列实现)和发布-订阅消息模型(主题)。

图1.点对点消息模型(一对一)

图2.发布-订阅消息模型(一对多)

二. 仅适用Jsm

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;
import org.apache.activemq.command.ActiveMQQueue; public class Testjsm {
public static void main(String[] args) throws JMSException {
ConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
// 连接
Connection conn = cf.createConnection();
// 创建回话
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建目的地,队列的名称
Destination destination = new ActiveMQQueue("SimperConteoller.topic");
// 创建发送者
MessageProducer producer = session.createProducer(destination);
// 创建发送内容
TextMessage message = session.createTextMessage();
message.setText("hello,大家好");
// 发送
producer.send(message);
} }

  步骤为:

     1.创建工厂 2.创建连接 3.创建会话 4.创建目的地 5.创建发送者 6.创建发送内容 7.发送者进行发送内容的发送

  代码步骤多,且异常不好处理。

二. 使用模板

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator; public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-jsm.xml");
JmsTemplate tem = (JmsTemplate) context.getBean("jmsTemplate");
Destination des = (Destination) context.getBean("topic");
tem.send(des, new MessageCreator() { public Message createMessage(Session arg0) throws JMSException { return arg0.createTextMessage("大家好!");
}
}); TextMessage ms = (TextMessage) tem.receive(des);
System.out.println("接受者是:" + ms); }
}

  步骤:只需要发送。使用JmsTemplate,可以创建连接,获得会话以及发送和接受消息,使代码专注于构建要发送的消息和处理接受到的消息。

  1.pom.xml
    <dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.12.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
  2. 链接,会话在xml管理
      1.连接activemq
      2.目的地
      3.格式转化器
      4.jsm模板发送
<?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:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
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-4.2.xsd"> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616">
</bean> <bean id="topic" class="org.apache.activemq.command.ActiveMQTopic" c:_="SimperConteoller.topic"></bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" c:_-ref="connectionFactory">
</bean> </beans>
三.JmsTemplate的源码分析
 tem.send(des, new MessageCreator() {

            public Message createMessage(Session arg0) throws JMSException {

                return arg0.createTextMessage("大家好!");
}
});

源代码:

    @Override
public void send(final Destination destination, final MessageCreator messageCreator) throws JmsException {
execute(new SessionCallback<Object>() {
@Override
public Object doInJms(Session session) throws JMSException {
doSend(session, destination, messageCreator);
return null;
}
}, false);
} 

  send函数:1. execute:创建连接与会话

2.doSend:创建发送者和发送内容,并发送

execute源代码:创建连接与会话

    public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException {
Assert.notNull(action, "Callback object must not be null");
Connection conToClose = null;
Session sessionToClose = null;
try {
Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
getConnectionFactory(), this.transactionalResourceFactory, startConnection);
if (sessionToUse == null) {
conToClose = createConnection();
sessionToClose = createSession(conToClose);
if (startConnection) {
conToClose.start();
}
sessionToUse = sessionToClose;
}
if (logger.isDebugEnabled()) {
logger.debug("Executing callback on JMS Session: " + sessionToUse);
}
return action.doInJms(sessionToUse);
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
finally {
JmsUtils.closeSession(sessionToClose);
ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
}
}

doSend源代码:创建发送者和发送内容,并发送

protected void doSend(Session session, Destination destination, MessageCreator messageCreator)
throws JMSException { Assert.notNull(messageCreator, "MessageCreator must not be null");
MessageProducer producer = createProducer(session, destination);
try {
Message message = messageCreator.createMessage(session);
if (logger.isDebugEnabled()) {
logger.debug("Sending created message: " + message);
}
doSend(producer, message);
// Check commit - avoid commit call within a JTA transaction.
if (session.getTransacted() && isSessionLocallyTransacted(session)) {
// Transacted session created by this template -> commit.
JmsUtils.commitIfNecessary(session);
}
}
finally {
JmsUtils.closeMessageProducer(producer);
}
}
    protected void doSend(MessageProducer producer, Message message) throws JMSException {
if (this.deliveryDelay >= 0) {
if (setDeliveryDelayMethod == null) {
throw new IllegalStateException("setDeliveryDelay requires JMS 2.0");
}
ReflectionUtils.invokeMethod(setDeliveryDelayMethod, producer, this.deliveryDelay);
}
if (isExplicitQosEnabled()) {
producer.send(message, getDeliveryMode(), getPriority(), getTimeToLive());
}
else {
producer.send(message);
}
}

  

1.异步消息Jms及其JmsTemplate的源代码分析,消息代理ActiveMQ的更多相关文章

  1. Android应用Activity、Dialog、PopWindow、Toast窗体加入机制及源代码分析

    [工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重劳动成果] 1 背景 之所以写这一篇博客的原因是由于之前有写过一篇<Android应用setCont ...

  2. Java设计模式-代理模式之动态代理(附源代码分析)

    Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...

  3. Oozie JMS通知消息实现--根据作业ID来过滤消息

    一,介绍 本文使用Oozie的消息通知功能,并根据JMS规范中的消息选择器(Selector)实现 根据作业的ID来过滤消息. 首先搭建好JMS Provider(ActiveMQ) ,并进行相关配置 ...

  4. JAVA消息 JMS 很重要

    首先大致讲一下,java 消息模块 消息,个人理解分为两种:1.同步消息(RPC调用) 2.异步消息(本篇讲解部分) 一.同步消息java提供了多种方案: 最新比较常用的方式就是spring Http ...

  5. Android异步任务处理框架AsyncTask源代码分析

    [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比方最常见的网络请求).遇到这样的问题.我 ...

  6. Raw-OS源代码分析之消息系统-Queue_Size

    分析的内核版本号截止到2014-04-15.基于1.05正式版.blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现"???"字样,则是未深究理解部分. Raw-OS官方 ...

  7. JMS学习(二)- JMS Message Model 组成介绍及消息头详解

    一.前言 从本文起依次详细介绍JMS中的一些重要的概念,主要参考了官方的JMS1.1的文档,该文档很老了,是02年的,那年,JAVA还没有被Oracle收购..本文主要介绍Message及其相关概念, ...

  8. Memcached源代码分析 - Memcached源代码分析之消息回应(3)

    文章列表: <Memcached源代码分析 - Memcached源代码分析之基于Libevent的网络模型(1)> <Memcached源代码分析 - Memcached源代码分析 ...

  9. RTMPdump(libRTMP) 源代码分析 10: 处理各种消息(Message)

    ===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...

随机推荐

  1. 控制WIFI状态

    1.控制WIFI public class MainActivity extends Activity { private Button startButton = null; private But ...

  2. python第一个hello world注意问题!!

    如果你第一次写python代码,想写一个通常的hello world ,那么你需要注意这个hello world的写法,这和python的版本有直接关系!!! Python 3.x: print('h ...

  3. code md5

    using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptograph ...

  4. 格式化日期的js(正则魅力)

      /** * 时间对象的格式化; */ Date.prototype.format = function(format) { // ◆ 使用prototype定义原型方法 /* * eg:forma ...

  5. 建立dblink

    源地址:http://blog.itpub.net/24104981/viewspace-1116085/ create database link dblinkname connect to use ...

  6. 05-UIKit绘图演练

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  7. 《Head First 设计模式》ch.1 策略(Strategy)模式

    策略模式 定义了算法族,分别封装起来,让它们可以互相替换,让算法的变化独立于使用算法的客户. 模式名词的意义 威力强大,交流的不止是模式名称,而是一整套模式背后所象征的质量.特性.约束 用更少的词汇做 ...

  8. python学习(二):python基本语法

    前言:python基本的语法与其他语言诸如C,JAVA等类似,但个中有些许不同. 一.常规语法 1.变量名与关键字 与其他语言类似,变量名由字母.数字.下划线组成,且必须由字母开头. 变量使用不需要提 ...

  9. LoadRunner界面分析(三)

    1.Anaysis基础知识 2.Analysis 报告 3.Analysis分析基础 4.IP欺骗 需要使用ip欺骗的原因:1.当某个IP的访问过于频繁,或者访问量过大是,服务器会拒绝访问请求,这时候 ...

  10. 百度富文本编辑器UEditor安装配置全过程

    网站开发时富文本编辑器是必不可少的,他可以让用户自行编辑内容的样式然后上传到后台!下面我们来介绍如何安装使用百度富文本编辑器 一.下载并且设置百度富文本编辑器的样式     你可以去百度UEditor ...