Announcement Announcement Module
Collapse
No announcement yet.
Doubt about Spring Asynchronous JMS support Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Doubt about Spring Asynchronous JMS support

    Dear all,
    I have a test on spring2.0's jms support. yes my program can run but the out confuse me! below is my environment and my code

    jdk1.5.8
    spring2.0.4
    activemq4.1.1
    xbean-spring3.1
    spring configure file : applicationContext-activemq-embedded.xml
    Code:
    <?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:amq="http://activemq.org/config/1.0"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
               http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-SNAPSHOT.xsd">
    
    	<amq:broker useJmx="false" persistent="false">
    		<amq:transportConnectors>
    			<amq:transportConnector uri="tcp://localhost:0" />
    		</amq:transportConnectors>
    	</amq:broker>
    
    	<!--  ActiveMQ connectionFactory  -->
    	<amq:connectionFactory id="jmsConnectionFactory"
    		brokerURL="vm://localhost" />
    
    	<!--  ActiveMQ destinations  -->
    	<amq:queue name="destination"
    		physicalName="org.apache.activemq.spring.Test.spring.embedded" />
    
    	<!--  Spring JmsTemplate config -->
    	<bean id="jmsTemplate"
    		class="org.springframework.jms.core.JmsTemplate">
    		<property name="connectionFactory">
    			<!--  lets wrap in a pool to avoid creating a connection per send -->
    			<bean
    				class="org.springframework.jms.connection.SingleConnectionFactory">
    				<property name="targetConnectionFactory"
    					ref="jmsConnectionFactory" />
    			</bean>
    		</property>
    
    	</bean>
    
    	<!-- POJO which send Message uses  Spring JmsTemplate -->
    	<bean id="orderMessageProducer"
    		class="com.xwcheng.jms.OrderMessageProducer">
    		<property name="template" ref="jmsTemplate" />
    		<property name="destination" ref="destination" />
    	</bean>
    
    	<!--  Message Driven POJO (MDP) -->
    	<bean id="messageListener"
    		class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
    		<constructor-arg>
    			<bean class="com.xwcheng.jms.OrderMessageConsumer"/>
    		</constructor-arg>
    		<!--  may be other method -->
    		<property name="defaultListenerMethod" value="sendMail" />
    	</bean>
    
    	<bean id="listenerContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    		<property name="connectionFactory" ref="jmsConnectionFactory" />
    		<property name="destination" ref="destination" />
    		<property name="messageListener" ref="messageListener" />
    	</bean>
    </beans>

    message producer
    Code:
    package com.xwcheng.jms;
    
    import javax.jms.Queue;
    
    import org.springframework.jms.core.JmsTemplate;
    
    public class OrderMessageProducer {
    	private JmsTemplate template;
    
    	private Queue destination;
    
    	public void setTemplate(JmsTemplate template) {
    		this.template = template;
    	}
    
    	public void setDestination(Queue destination) {
    		this.destination = destination;
    	}
    
    	public void send() {
    		template.convertAndSend(this.destination, "Hello so nice to meet you");
    	}
    
    }
    message consumer

    Code:
    package com.xwcheng.jms;
    
    import javax.jms.Message;
    import javax.jms.MessageListener;
    import javax.jms.TextMessage;
    
    
    public class OrderMessageConsumer {
    
    	public void sendMail(String text) {
    		System.out.println(text);
    	}
    
    }
    test class

    Code:
    package com.xwcheng.jms;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("com/xwcheng/jms/applicationContext-activemq-embedded.xml");
    		OrderMessageProducer producer =  (OrderMessageProducer) ctx.getBean("orderMessageProducer");
    		producer.send();
    		System.out.println("good afternoon !");
    	}
    }
    the out form console:

    Code:
    Hello so nice to meet you
    good afternoon !
    Question:
    1: the output form console indicates that the message consumer is execute before the caller. i think as it is a Asynchronous way so the out should be
    "good afternoon !" first then "Hello so nice to meet you"

    2: Spring support Asynchronous way jms must using "org.springframework.jms.listener.adapter.MessageL istenerAdapter"

    3: refer to http://activemq.apache.org/how-do-i-...s-sending.html

    then how can enable Asynchronous jms using spring configure xml file

  • #2
    The order of console output doesn't give an indication whether this is actually executed asynchronously or not. The consumer's thread might simply execute the println statement before your main thread reaches its println statement.

    Try adding a sleep statement to your listener before the println... Then you increase the chance of the caller's println executing first.

    A quick option to actually find about asynchronous execution is to add the thread name to the output there: Thread.currentThread().getName() - this should show different threads for the caller and the listener.

    Juergen

    Comment


    • #3
      Thank you your reply!
      I have another question:
      If I want to use Asynchronous way jms must I using with "org.springframework.jms.listener.adapter.Mess ageL istenerAdapter" ?

      Comment


      • #4
        Hello,

        there is no need to use the MessageListenerAdapter. (The Adapter is very handy because you don't have any dependency to any jms api or spring api).

        You can also implement org.springframework.jms.listener.SessionAwareMessa geListener (if you want access to the session), or directly javax.jms.MessageListener (if you want to use jms apis).

        You have to inject your particular messageListener into the container, and remove the messagelistener adapter bean definition.

        rgds
        agim

        Comment

        Working...
        X