`
wusuoya
  • 浏览: 641652 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

spring jms _ activemq

    博客分类:
  • SSH
 
阅读更多
参考链接:
http://bsnyderblog.blogspot.com/2010/02/using-spring-jmstemplate-to-send-jms.html
http://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive-jms-messages.html

Recently I stumbled upon a number of places in the some docs and mailing lists where claims are made that the Spring JmsTemplate is full of anti-patterns, is horribly inefficient and shouldn't be used. Well I'm here to debunk these erroneous claims by pointing out a class in the Spring Framework that was overlooked entirely.

The Spring JmsTemplate is a convenience class for sending and receiving JMS messages in a synchronous manner. The JmsTemplate was originally designed to be used with a J2EE container where the container provides the necessary pooling of the JMS resources (i.e., connections, consumers and producers). Such requirements came from the EJB spec. But when developers began using the JmsTemplate outside of J2EE containers, and because some JMS providers do not offer caching/pooling of JMS resources, a different solution was necessary. Enter the Spring CachingConnectionFactory.

The CachingConnectionFactory is meant to wrap a JMS provider's connection to provide caching of sessions, connections and producers as well as automatic connection recovery. By default, it uses a single session to create many connections and this model works very well with most MOMs. But if you need to scale further, you can also specify the number of sessions to cache using the sessionCacheSize property.

Below is a snippet from a Spring app context that demonstrates the configuration for the CachingConnectionFactory

01
...
02

03
<!-- A connection to ActiveMQ -->
04

05
<bean id="amqConnectionFactory"
06

07
    class="org.apache.activemq.ActiveMQConnectionFactory"
08

09
    p:brokerURL='tcp://localhost:61616" />
10

11

12

13
<!-- A cached connection to wrap the ActiveMQ connection -->
14

15
<bean id="cachedConnectionFactory"
16

17
    class="org.springframework.jms.connection.CachingConnectionFactory"
18

19
    p:targetConnectionFactory-ref="amqConnectionFactory"
20

21
    p:sessionCacheSize="10" />
22

23

24

25
<!-- A destination in ActiveMQ -->
26

27
<bean id="destination"
28

29
    class="org.apache.activemq.command.ActiveMQQueue">
30

31
<constructor-arg value="FOO.TEST" />
32

33
</bean>
34

35

36

37
<!-- A JmsTemplate instance that uses the cached connection and destination -->
38

39
<bean id="producerTemplate"
40

41
    class="org.springframework.jms.core.JmsTemplate"
42

43
    p:connectionFactory-ref="cachedConnectionFactory"
44

45
    p:defaultDestination-ref="destination" />
46

47
...


As you can see, the configuration for the CachingConnectionFactory along with the JmsTemplate is quite simple. Furthermore, these two classes are also both in the org.springframework.jms package path so they're both included in the spring-jms jar file making their use even easier.

The only thing left to do is utilize the jmsTemplate bean in your Java code to actually send a message. This is shown below:

01
public class SimpleMessageProducer {
02

03
    
04

05
    private static final Logger LOG = Logger.getLogger(SimpleMessageProducer.class);
06

07
    
08

09
    @Autowired
10

11
    protected JmsTemplate jmsTemplate;
12

13
    
14

15
    protected int numberOfMessages = 100;
16

17
    
18

19
    public void sendMessages() throws JMSException {
20

21
        StringBuilder payload = null;
22

23
        
24

25
        for (int i = 0; i < numberOfMessages; ++i) {
26

27
            
28

29
            payload = new StringBuilder();
30

31
            payload.append("Message [").append(i).append("] sent at: ").append(new Date());
32

33
            
34

35
            jmsTemplate.send(new MessageCreator() {
36

37
                public Message createMessage(Session session) throws JMSException {
38

39
                    TextMessage message = session.createTextMessage(payload.toString());
40

41
                    message.setIntProperty("messageCount", i);
42

43
                    LOG.info("Sending message number [" + i + "]");
44

45
                    return message;
46

47
                }
48

49
            });
50

51
        }
52

53
    }
54

55
}


The SimpleMessageProducer class above demonstrates the use of Spring autowiring to resolve the relationship between the jmsTemplate property and the producerTemplate in the app context further above. Then an anonymous MessageCreator instance is used to actually create a message for the jmsTemplate to send.

The JmsTemplate and the CachingConnectionFactory are both very widely used in businesses of all sizes throughout the world. Coupled with one of the Spring message listener containers, they provide an ideal solution.

I'll elaborate on message consumption using the Spring DefaultMessageListenerContainer and the SimpleMessageListenerContainer in a future blog post.


Have you ever had a need to create your own JMS consumer? Or will you have this need in the future? If you answered yes to either one of these questions, this post will simplify your life.

In the previous post, I discussed Using the Spring JmsTemplate to Send JMS Messages. As a follow-on, in this post I will demonstrate how to receive messages using Spring JMS. Although the previously mentioned JmsTemplate can receive messages synchronously, here I will focus on asynchronous message reception using the Spring message listener container architecture, specifically the DefaultMessageListenerContainer.

The DefaultMessageListenerContainer (DMLC) is another wonderful convenience class that is part of the Spring Framework's JMS package. As you can see in the Javadoc, the DMLC is not a single class, but a well-abstracted hierarchy for the purpose of receiving messages. The reason for this is that the DMLC takes its inspiration from Message Driven Beans (MDB).

MDBs were originally defined in the EJB 2.0 spec as a stateless, transaction aware message listener that use JMS resources provided by the Java EE container. MDBs can also be pooled by the Java EE container in order to scale up. In short, MDBs were designed for asynchronous message reception in a way that the Java EE container could manage them. Although the intention was good, unfortunately the disadvantages of MDBs are numerous including:
MDBs are static in their configuration and creation (they cannot be created dynamically)
MDBs can only listen to a single destination
MDBs can only send messages after first receiving a message
MDBs require an EJB container (and therefore the Java EE container)
Although the Spring DMLC took its inspiration from MDBs, it did not replicate these disadvantages; quite the opposite, in fact. The Spring DMLC is commonly used to create what have become known as Message-Driven POJOs (MDP). MDPs offer all of the same functionality as MDBs but without the disadvantages listed above. The Spring DMLC provides many features including:
Various levels of caching of the JMS resources (connections and sessions) and JMS consumers for increased performance
The ability to dynamically grow and shrink the number of consumers to concurrently process messages based on load (see setConcurrentConsumers and setMaxConcurrentConsumers) for additional performance
Automatically re-establishes connections if the message broker becomes unavailable
Asynchronous execution of a message listener using the Spring TaskExecutor
Support for local JMS transactions as well as an external transaction manager around message reception and listener execution
Support for various message acknowledgement modes, each providing different semantics
For some situations, it is important to understand the additional error handling and the redelivery semantics that are provided by the DMLC. For more information, see the AbstractMessageListenerContainer JavaDoc.

The reason I recommend the DMLC (or even the SimpleMessageListenerContainer) is because writing JMS consumers can be a lot of work. In doing so, you must manually handle and mange the JMS resources and the JMS consumers, any concurrency that is necessary and any use of transactions. If you've ever done such work you know how arduous and error prone it can be. Certainly MDBs provide some of these features but with all their disadvantages. By creating MDPs using the Spring DMLC, I have seen users save a tremendous amount of time and increase their productivity significantly. This is because the DMLC offers much flexibility, robustness, a high amount of configurability and it has widespread deployment in businesses all over the world (so it has been widely tested).

Compared to MDBs, use of the Spring DMLC is actually surprisingly simple. The easiest way to get started is to using an XML configuration as the Spring DMLC provides JMS namespace support. Below is a Spring application context that demonstrates the configuration to use the Spring DMLC with Apache ActiveMQ:

01
<?xml version="1.0" encoding="UTF-8"?>
02
<beans xmlns="http://www.springframework.org/schema/beans"
03
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04
       xmlns:jms="http://www.springframework.org/schema/jms"
05
       xmlns:p="http://www.springframework.org/schema/p"
06
       xsi:schemaLocation="
07
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
08
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">
09

10
  <!-- A JMS connection factory for ActiveMQ -->
11
  <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
12
  p:brokerURL="tcp://foo.example.com:61616" />
13

14
  <!-- A POJO that implements the JMS message listener -->
15
  <bean id="simpleMessageListener" class="com.mycompany.SimpleMessageListener">
16

17
  <!-- The Spring message listener container configuration -->
18
  <jms:listener-container
19
      container-type="default"
20
      connection-factory="connectionFactory"
21
      acknowledge="auto">
22
    <jms:listener destination="TEST.FOO" ref="simpleMessageListener" method="onMessage" />
23
  </jms:listener-container>
24
</beans>


For folks who are already familiar with the Spring Framework, the XML above is quite straightforward. It defines a connection factory bean for ActiveMQ, a message listener bean and the Spring listener-container. Notice that the jms:listener contains the destination name and not the listener-container. This level of separation is important because it means that the listener-container is not tied to any destination, only the jms:listener is. You can define as many jms:listener elements as is necessary for your application and the container will handle them all.

Below is the message listener implementation:

01
import javax.jms.JMSException;
02
import javax.jms.Message;
03
import javax.jms.MessageListener;
04
import javax.jms.TextMessage;
05

06
import org.apache.log4j.Logger;
07

08
public class MyMessageListener implements MessageListener {
09

10
  private static final Logger LOG = Logger.getLogger(MyMessageListener.class);
11

12
  public void onMessage(Message message) {
13
      try {
14
       TextMessage msg = (TextMessage) message;
15
       LOG.info("Consumed message: " + msg.getText());
16
      } catch (JMSException e) {
17
          // TODO Auto-generated catch block
18
          e.printStackTrace();
19
      }
20
  }
21

22
}

The message listener implementation is deliberately simple as its only purpose is to demonstrate receiving the message and logging the payload of the message. Although this listener implements the javax.jms.MessageListener interface, there are a total of three options available for implementing a message listener to be used with the Spring DMLC:
The javax.jms.MessageListener - This is what was used in the example above. It is a standardized interface from the JMS spec but handling threading is up to you.
The Spring SessionAwareMessageListener - This is a Spring-specific interface the provides access to the JMS session object. This is very useful for request-response messaging. Just be aware that you must do your own exception handling (i.e., override the handleListenerException method so exceptions are not lost).
The Spring MessageListenerAdapter - This is a Spring-specific interface that allows for type-specific message handling. Use of this interface avoids any JMS-specific dependencies in your code.


So not only is the Spring message listener container easy to use, it is also full of options to adapt to many environments. And I've only focused on the DefaultMessageListenerContainer here, I have not talked about the SimpleMessageListenerContainer (SMLC) beyond a simple mention. At a high level the difference is that the SMLC is static and provides no support for transactions.

One very big advantage of the Spring message listener container is that this type of XML config can be used in a Java EE container, in a servlet container or stand alone. This same Spring application context will run in Weblogic, JBoss, Tomcat or in a stand alone Spring container. Furthermore, the Spring DMLC also works with just about any JMS compliant messaging middleware available. Just define a bean for the JMS connection factory for your MOM and possibly tweak a few properties on the listener-container and you can begin consuming messages from different MOMs.

I should also note that the XML configuration is certainly not a requirement either. You can go straight for the underlying Java classes in your own code if you wish. I've used each style in various situations, but to begin using the Spring DMLC in the shortest amount of time, I find the Spring XML application context the fastest.
分享到:
评论

相关推荐

    Spring-ActiveMQ.rar_Spring Activemq_activemq_activemq spring

    ActiveMQ是Apache软件基金会的一个开源项目,它是Java消息服务(JMS)的一个实现,广泛应用于企业级应用中。而Spring框架,作为一个Java平台的全功能模块化解决方案,提供了与ActiveMQ集成的能力,让开发者能够轻松...

    JMS_ActiveMQ_Spring.rar

    《JMS、ActiveMQ与Spring整合的深度解析》 Java消息服务(Java Message Service,简称JMS)是Java平台中用于在分布式环境中交换异步消息的标准API。它为应用程序提供了创建、发送、接收和阅读消息的接口,允许应用...

    SpringJMS整合ActiveMQ

    详细内容: SpringJMS整合ActiveMQ.doc 详细说明文档 apache-activemq-5.8.0-bin.zip ActiveMQ安装包 JMSTest.rar MyEclipse8.5下web工程

    activeMQ_spring_Demo.zip_DEMO_activemq_activemq spring_rowbv3

    ActiveMQ作为Apache基金会的一个开源项目,是Java消息服务(JMS)的一个实现,而Spring框架则广泛应用于Java后端开发,提供了一整套的轻量级容器服务。本教程将重点讲解如何将ActiveMQ与Spring进行整合,以创建一个...

    spring整合jms+activemq

    本文将深入探讨如何在Spring 3.0中整合JMS与ActivemQ,以及它们在实际应用中的关键知识点。 首先,我们要了解Spring对JMS的支持。Spring通过其`org.springframework.jms`包提供了丰富的JMS抽象,简化了JMS的使用。...

    Spring+JMS+ActiveMQ+Tomcat实现消息服务的demo

    基于Spring+JMS+ActiveMQ+Tomcat,我使用的版本情况如下所示:Spring 3.2.0,ActiveMQ 5.4.3,Tomcat 6.0.43。本例通过详细的说明和注释,实现消息服务的基本功能:发送与接收。Spring对JMS提供了很好的支持,可以...

    activeMQ_spring简单案例(含XML配置)

    在实际应用中,`activeMQ_p2s`和`activeMQ_spring`这两个文件可能包含了示例代码,分别展示了生产者(Producer)和消费者(Consumer)的实现。生产者通常会使用`JmsTemplate`发送消息,而消费者则通过实现`Message...

    Apache_ActiveMQ教程

    例如,ActiveMQ具有很好的Spring支持,允许开发者在Spring应用中轻松地集成ActiveMQ,并利用Spring提供的依赖注入和事务管理功能。另外,ActiveMQ社区提供了各种插件和扩展来支持不同的消息模式和协议,使得ActiveMQ...

    品优购_day13_SpringJms_V1.31

    【品优购电商系统开发第13章:SpringJms_V1.31】课程主要讲解了消息中间件解决方案,特别是Java消息服务(JMS)的使用,旨在帮助开发者理解和掌握消息中间件的重要概念和实际操作。以下是相关知识点的详细说明: 1....

    activemq_activemq_doublezoo_源码

    在“activemq_activemq_doublezoo_源码”这个主题中,我们主要关注两个关键概念:ActiveMQ的生产者和消费者API,以及ActiveMQ与Spring框架的整合。 1. **ActiveMQ生产者API**: 生产者是向消息队列发布消息的组件...

    Spring 实现远程访问详解——jms和activemq

    本章我将通过spring jms和activemq实现单Web项目服务器间异步访问和多Web项目服务器间异步访问。 一. 简介 1. 什么是Apache ActiveMq Apache ActiveMq是最流行和最强大的开源消息和集成服务器。同时Apache ActiveMq...

    activemq_spring.rar_Spring和ActiveMQ_spring_消息中间件_消息发布订阅_消息订阅

    Spring对消息中间件的支持主要体现在Spring的JMS模块,它提供了一套API,可以帮助开发者轻松地与各种JMS提供商(如ActiveMQ)进行交互。 Spring与ActiveMQ的整合过程主要包括以下步骤: 1. **添加依赖**:在项目中...

    msg-web.zip_activemq_msg active 2_msg-active_msg_active_msgactiv

    本示例“msg-web.zip_activemq_msg active 2_msg-active_msg_active_msgactiv”关注的是如何利用Spring Integration与ActiveMQ进行集成,以实现高效、可靠的消息传递。 首先,我们需要理解Spring Integration。它是...

    SpringJMS示例代码

    在本文中,我们将深入探讨SpringJMS的基本概念、如何与ActiveMQ集成,以及如何通过示例代码理解其工作原理。 1. **SpringJMS简介** SpringJMS是Spring框架对JMS API的包装,它简化了生产者和消费者之间的消息通信...

    spring+jms+activemq

    本文将深入探讨如何使用Spring框架与ActiveMQ结合实现基于JMS的消息传递系统。 首先,理解JMS的基本概念至关重要。JMS定义了生产者(Producer)、消费者(Consumer)和消息队列(Queue)或主题(Topic)等核心组件...

    Spring+JMS+ActiveMQ+Tomcat jar下载

    Spring、JMS、ActiveMQ和Tomcat是Java开发中常用的技术组件,它们分别扮演着不同的角色,构建出高效的企业级消息通信系统。本教程将详细阐述这些技术的使用及其相互结合的方式。 首先,Spring是一个开源的Java应用...

    jms Spring+ActiveMQ 5.4.2

    标题 "jms Spring+ActiveMQ 5.4.2" 涉及的是Java消息服务(JMS)在Spring框架中的应用,以及ActiveMQ作为消息代理的使用。在这个主题下,我们将深入探讨JMS的基本概念、Spring对JMS的支持以及ActiveMQ 5.4.2版本的...

    Apache_ActiveMQ教程.docx

    此外,ActiveMQ还具有优秀的Spring框架支持,使得集成到Spring应用中变得极其便捷。其性能表现优越,通常比JBossMQ快10倍,且得益于Apache社区的支持,ActiveMQ拥有持续发展的潜力。 在部署Apache ActiveMQ时,首先...

    JMS之Spring +activeMQ实现消息队列

    总结起来,"JMS之Spring + ActiveMQ实现消息队列"涉及到的关键知识点包括:Spring框架的JMS支持、ActiveMQ的使用、ConnectionFactory的配置、JmsTemplate和MessageListener的实现,以及消息队列在解决系统解耦和异步...

Global site tag (gtag.js) - Google Analytics