MyException - 我的异常网
当前位置:我的异常网» 开源软件 » Spring-JMS课程2

Spring-JMS课程2

www.MyException.Cn  网友分享于:2013-11-16  浏览:0次
Spring-JMS教程2

转自:http://blog.csdn.net/suifeng3051/article/details/51721141

本篇文章主要描述了如何配置Spring-JMS,至于为何这样配置及Spring-JMS相关介绍,请阅读这篇文章:Spring整合JMS(消息中间件)。我们这里的消息broker用的是ActiveMQ。

一、相关配置

本篇主要讲解如何在Spring中配置JMS,关于Spring本身的配置本文就不多做介绍了。

1.1 配置maven依赖

在使用Spring-JMS之前,先配置相关依赖。

<!-- Java JMS 原生API -->
<dependency>
   <groupId>javax.jms</groupId>
   <artifactId>javax.jms-api</artifactId>
   <version>2.0</version>
</dependency>
<!-- spring-jms API -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jms</artifactId>
   <version>${spring.version}</version>
</dependency>
<!-- active-mq核心包 -->
<dependency>
   <groupId>org.apache.activemq</groupId>
   <artifactId>activemq-core</artifactId>
   <version>5.7.0</version>
</dependency>
<!-- spring-test类用来测试 -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring.version}</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

 1.2 安装并启动ActiveMQ

这里只是简单介绍如何安装启动ActiveMQ,详细请参考官方文档。

  1. 下载ActiveMQ:http://activemq.apache.org/download.html
  2. 安装: 
    - 解压:tar zxvf activemq-x.x.x-bin.tar.gz 
    - 增加权限: 
    cd [activemq_install_dir]/bin 
    chmod 755 activemq

  3. 启动: 
    cd [activemq_install_dir]/bin 
    ./activemq start

  4. 检查是否启动成功: 
    netstat -nl|grep 61616

我们还可以通过监控页面查看ActiveMQ运行情况:http://localhost:8161/admin (默认用户名密码都是admin)

1. 3 配置JMS相关bean

<?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:context="http://www.springframework.org/schema/context"
   xmlns:jms="http://www.springframework.org/schema/jms"
   xmlns:amq="http://activemq.apache.org/schema/core"
   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
                       http://www.springframework.org/schema/jms
                       http://www.springframework.org/schema/jms/spring-jms.xsd
                       http://activemq.apache.org/schema/core
                       http://activemq.apache.org/schema/core/activemq-core.xsd">

<!-- 配置连接ActiveMQ的ConnectionFactory -->
<bean id="amqConnectionFactory"
      class="org.apache.activemq.ActiveMQConnectionFactory"
      p:brokerURL="tcp://localhost:61616"/>
<!--为了提高效率,配置一个连接池-->
<bean id="cachedConnectionFactory"
      class="org.springframework.jms.connection.CachingConnectionFactory"
      p:targetConnectionFactory-ref="amqConnectionFactory"
      p:sessionCacheSize="10"/>
<!-- 配置broker的destination-->
<bean id="destination"
      class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg value="FOO.TEST"/>
</bean>
<!-- 配置Spring的JmsTemplate -->
<bean id="producerTemplate"
      class="org.springframework.jms.core.JmsTemplate"
      p:connectionFactory-ref="cachedConnectionFactory"
      p:defaultDestination-ref="destination"/>
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

从这个配置中可以看到,这里的配置比Spring整合JMS(消息中间件)文章中介绍的多了一个cachedConnectionFactory配置。我们知道创建和销毁连接是非常消耗资源的,为了解决创建销毁连接带来的资源消耗,我们一般会引入连接池(Pool)或者缓存(Cache)。普通的JmsTemplate的ConnectionFactory每次发送消息时都需要建立新的连接,这样效率是非常低的,所以在具体配置时,我们要尽量用到连接池或缓存,所以这里的配置中加了一个cachedConnectionFactory作为缓存。

二、发送消息

写一个JmsMessageProducer异步发送消息:

@Component
public class JmsMessageProducer {
    private static final Logger logger = LoggerFactory.getLogger(JmsMessageProducer.class);
    @Autowired
    protected JmsTemplate jmsTemplate;
    protected int numberOfMessages = 10;

    public void sendMessages() throws JMSException {
        StringBuilder payload = null;
        for (int i = 0; i < numberOfMessages; ++i) {
            payload = new StringBuilder();
            payload.append("Message [").append(i).append("] sent at: ").append(new Date());
            jmsTemplate.convertAndSend(payload.toString());
            logger.info("Sending message number [" + i + "]");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

三、接收消息

3.1 方式一:写一个JmsMessageConsumer 同步接收消息

@Component
public class JmsMessageConsumer {
    private static final Logger logger = LoggerFactory.getLogger(JmsMessageProducer.class);
    @Autowired
    private JmsTemplate template;
    public void receiveMessages() throws JMSException {
        Message message =template.receive();
        TextMessage textMessage =(TextMessage)template.receive();
        logger.info(textMessage.getText());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.2 方式二:写一个JmsMessageListener监听器异步接收消息

@Component
public class JmsMessageListener implements MessageListener{
    private static final Logger logger = LoggerFactory.getLogger(JmsMessageListener.class);
    public void onMessage(Message message) {
        try {
            TextMessage msg = (TextMessage) message;
            logger.info("Consumed message: " + msg.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

写完listener之后还需要在配置文件中配置这个listener:

<!-- 注入我们写的listener -->
<bean id="jmsMessageListener" class="com.heaven.spring.jms.JmsMessageListener"/>

<!-- 配置listener到listener-container当中 -->
<jms:listener-container
        container-type="default"
        connection-factory="cachedConnectionFactory"
        acknowledge="auto">
    <jms:listener destination="FOO.TEST" ref="jmsMessageListener" method="onMessage"/>
</jms:listener-container>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

四、测试一下

4.1 测试发送异步消息

写一个JmsMessageProducerTest测试一下发送:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/root-context.xml")
public class JmsMessageProducerTest {
    @Autowired
    JmsMessageProducer jmsMessageProducer;
    @Test
    public void testSend(){
        try {
            jmsMessageProducer.sendMessages();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

看一下运行结果:

这里写图片描述

消息已经异步发送成功,虽然还没有消费者消费,消息就像被成功处理一样。

4.2 测试同步接收消息

写一个JmsMessageConsumerTest 测试一下接收:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/root-context.xml")
public class JmsMessageConsumerTest {
    @Autowired
    JmsMessageConsumer jmsMessageConsumer;
    @Test
    public void testSend(){
        try {
            jmsMessageConsumer.receiveMessages();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

看一下运行结果:

这里写图片描述

我们可以看到消费者接收到一条消息,这条消息正是上面发送者发送的第一条消息。如果我们再运行一遍则会收到第二条消息。如果所有消息都消费完了,broker中没有消息了,此时JmsMessageConsumerTest进程便会挂起一直等待,直到有新消息产生,大家可以试一下。

4.3测试一下异步消息接收

按照上面3.2节写介绍一个JmsMessageListener并将其配置到 listener-container中。此时JmsMessageListener便会实时监听brokerURL="tcp://192.168.134.128:61616"这个端口,一旦有消息产生,便会在onMessage()方法接收到消息。其实此时我们的producer和监听器都在同一个应用中,如果我们再运行producer,可以看到如下结果: 
这里写图片描述

通过运行结果可以看到,每当生产者生产消息,监听器便会实时接收到消息。

 

文章评论

科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员的鄙视链
程序员的鄙视链
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
程序员应该关注的一些事儿
程序员应该关注的一些事儿
旅行,写作,编程
旅行,写作,编程
 程序员的样子
程序员的样子
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
那些争议最大的编程观点
那些争议最大的编程观点
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
每天工作4小时的程序员
每天工作4小时的程序员
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
如何成为一名黑客
如何成为一名黑客
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
老程序员的下场
老程序员的下场
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员和编码员之间的区别
程序员和编码员之间的区别
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
我的丈夫是个程序员
我的丈夫是个程序员
为什么程序员都是夜猫子
为什么程序员都是夜猫子
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
10个调试和排错的小建议
10个调试和排错的小建议
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
编程语言是女人
编程语言是女人
程序员都该阅读的书
程序员都该阅读的书
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
漫画:程序员的工作
漫画:程序员的工作
我是如何打败拖延症的
我是如何打败拖延症的
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
代码女神横空出世
代码女神横空出世
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员必看的十大电影
程序员必看的十大电影
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有