1. 概述:Spring提供了一个用于简化JMS API使用的抽象框架,并且对用户屏蔽了JMS API中1.0.2和1.1版本的差异。 
JMS的功能大致上分为两块,叫做消息制造和消息消耗。JmsTemplate 用于制造消息和同步消息接收。我们今天就用JmsTemplate实现同步的消息接受。 
使用JMS发(接)消息的步骤: 
  1)创建连接工厂 
  2)使用连接工厂创建连接 
  3)使用连接创建会话 
  4)获取一个目的地 
  5)使用会话和目的地创建消息生产者(消息消费者) 
  6)使用连接创建一个需要发送的消息类型实例 
  7)使用连接的一个队列发送器或主题公布器,使用发送器或者主题器发送消息(接受消息)

spring中的JmsTemplate实现了对jms的一些封装,内部提供了很多的方法,我们只需要实现定义的回调接口即可。JmsTemplate继承自JmsAccessor,在JmsAccessor中有ConnectionFactory的定义,而JmsTemplate本身的构造方法也有对ConnectionFactory的封装: 
Java代码

public JmsTemplate(ConnectionFactory connectionFactory) {   
            this();   
            setConnectionFactory(connectionFactory);   
            afterPropertiesSet();   
    }

所以,我们有两种方式注入ConnectionFactory,本文我们采用构造方法的方式。

spring_jms.xml 
Java代码

<?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-3.0.xsd">   
               
    <!-- 这里我们用构造方法注入 connectionFactory-->   
    <bean id = "jmsTemplate" class = "org.springframework.jms.core.JmsTemplate">   
        <constructor-arg ref="connectionFactory"></constructor-arg>   
    </bean>   
      
    <!-- 使用activemq中的连接工厂,提供一个brokerUrl,这里表示本地 -->   
    <bean id = "connectionFactory" class = "org.apache.activemq.ActiveMQConnectionFactory">   
        <property name="brokerURL" value="vm://localhost" />   
    </bean>   
      
    <!-- 使用activemq中的点对点消息模型,随意指定一个地址 -->   
    <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">   
            <constructor-arg value="test/queue"/>   
    </bean>   
      
    </beans>

MessageCreator 回调接口通过JmsTemplate中调用代码提供的Session来创建一条消息。 
看一下MessageCreator接口: 
Java代码

public interface MessageCreator {   
      
        Message createMessage(Session session) throws JMSException;   
      
    }

那么,我们来实现发送和接受消息DummyJms类 
Java代码

public class DummyJms {   
          
        public static void main(String[] args) throws Exception{   
            ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");   
            JmsTemplate jmsTemplate = (JmsTemplate)context.getBean("jmsTemplate");   
            Destination destination = (Destination)context.getBean("destination");   
               
            jmsTemplate.send(destination, new MessageCreator(){   
                      
                    public Message createMessage(Session session)   
                            throws JMSException {   
                        return session.createTextMessage("send message ");   
                    }   
                      
                   
            });   
               
            TextMessage msg = (TextMessage)jmsTemplate.receive(destination);   
            System.out.println("receive message = " + msg.getText());   
               
        }   
          
    }

输出结果: 
receive message = send message

可是我们并没有看到的像前文描述的那那些创建消息生产者,消息消费者的一些东西。继续分析,我们可以看一下, 
jmsTemplate.send(Destination destination,MessageCreator messageCreator)这里到底做了什么,可以让我们不费吹灰之力,就可以实现消息的发送。JmsTemplate源代码:

Java代码

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

JmsTemplate实现了JmsOperations接口,在JmsOperations里有 
Java代码

<T> T execute(SessionCallback<T> action) throws JmsException;

的定义。

那么这个SessionCallback接口是什么呢?它也为用户提供了JMS session。

Java代码

public interface SessionCallback<T> {   
      
        T doInJms(Session session) throws JMSException;   
      
    }

继续往下看。doSend方法:

Java代码

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);   
            }   
        }

createProducer()方法又调用了doCreateProducer(),实际的消息生产者在这里。 
Java代码

protected MessageProducer doCreateProducer(Session session, Destination destination) throws JMSException {   
            return session.createProducer(destination);   
        }

在这里,我们看到了,spring创建了消息的发送者,关闭连接的一些操作。到这里,大家就明白了,spring内部处理Jms消息的过程了吧(消息的接受也是一样)。

spring jsm(一)相关推荐

  1. spring jsm(二)

    JMS简介:一种应用于异步消息传递的标准API,JMS也是应用于程序间通讯的.但是,JMS与其他机制有所不同,主要表现在系统间传递信息的方式,见PPT1-2.简介传送也是JMS的关键.当一个应用程序通 ...

  2. Spring-JMS(一)spring整合JSM之activeMQ

    导入依赖 <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq- ...

  3. spring源码分析之spring-jms模块详解

    0 概述 spring提供了一个jms集成框架,这个框架如spring 集成jdbc api一样,简化了jms api的使用. jms可以简单的分成两个功能区,消息的生产和消息的消费.JmsTempl ...

  4. 如何使用消息队列,Spring Boot和Kubernetes扩展微服务

    by Daniele Polencic 由Daniele Polencic 如何使用消息队列,Spring Boot和Kubernetes扩展微服务 (How to scale Microservic ...

  5. 浅谈spring中的设计模式(转)

    工厂模式 BeanFactory,从xml或者注解加载BeanDefinition,然后实例化对象,其中AbstractAutowiredCapableBeanFactory实现了主要的逻辑 单例模式 ...

  6. 浅谈Spring设计模式

    工厂模式 BeanFactory,从xml或者注解加载BeanDefinition,然后实例化对象,其中AbstractAutowiredCapableBeanFactory实现了主要的逻辑 单例模式 ...

  7. spring boot项目 中止运行 最常用的几种方法

    spring boot项目 中止运行 最常用的几种方法: 1. 调用接口,停止应用上下文 @RestController public class ShutdownController impleme ...

  8. html+spring boot简单的ajax数据传输实现

    本篇讲解在前后端不分离情况下的html+spring boot的项目数据传输实现 首先,后台我写了三个接口 package com.demo.ajax.controller;import com.de ...

  9. Spring Boot整合Spring Data JPA操作数据

    一. Sping Data JPA 简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套 JPA 应用框架,底层使用了 Hibernate 的 J ...

最新文章

  1. 基于Redis实现分布式锁
  2. MyEclipse2017:MyEclipse2017软件破解图文教程(解决MyEclipse软件因试用期过期而无法再次使用的问题)
  3. 大厂产品专家是怎么做项目的?
  4. 6月2日,网易云信SDK全面支持IPv6
  5. 聚焦视频文本检索:一文概览视频文本检索任务最新研究进展
  6. python学习高级篇(part7)--特殊属性和特殊方法
  7. 阿卡接口_阿卡vs风暴
  8. Bran的内核开发指南_中文版
  9. 最全的Vue3.0新特性预览(翻译)
  10. 数据结构顺序表基本操作(C/C++实现)
  11. 测试 linux CPU 压力
  12. 集成学习之Bagging与随机森林算法原理小结
  13. 七大江河水系--淮河
  14. BigDecimal精度丢失处理
  15. 技术干货 | Linkis实践:新引擎实现流程解析
  16. Objective-C的方法替换
  17. mx550和锐炬xe显卡差距大 锐炬xe显卡和mx550区别哪个好
  18. ubuntu 有key登入sshd Failed publickey for xxx from xx port Xxx ssh2
  19. 字节流与字符流(一)
  20. cad.net GeometricExtents出错了 调试看不到文字

热门文章

  1. SAR成像系列:【5】合成孔径雷达(SAR)成像算法-距离多普勒(RD)算法(附Matlab代码)
  2. 【FFmpeg】flv转码测试2: 24fps gop为24 恒定码率
  3. Clark变换与Park
  4. 生成函数多项式操作合集
  5. js数组实现图片轮播
  6. jFreeChart+itext生成带统计图的pdf文件
  7. 嵌入式linux qos tc,iptables和tc脚本实现智能QOS
  8. 数据库的概念设计与逻辑设计
  9. Wormhole大数据流式处理平台五大功能
  10. LocalDateTime用法