Spring + ActiveMQ實現jms發送消息

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代碼
 

 

  1. public JmsTemplate(ConnectionFactory connectionFactory) {   
  2.         this();   
  3.         setConnectionFactory(connectionFactory);   
  4.         afterPropertiesSet();   
  5. }  

因此,咱們有兩種方式注入ConnectionFactory,本文咱們採用構造方法的方式。

spring_jms.xml
Java代碼
 

 

  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">   
  5.            
  6. <!-- 這裏咱們用構造方法注入 connectionFactory-->    
  7. <bean id = "jmsTemplate" class = "org.springframework.jms.core.JmsTemplate">   
  8.     <constructor-arg ref="connectionFactory"></constructor-arg>   
  9. </bean>   
  10.   
  11. <!-- 使用activemq中的鏈接工廠,提供一個brokerUrl,這裏表示本地 -->   
  12. <bean id = "connectionFactory" class = "org.apache.activemq.ActiveMQConnectionFactory">   
  13.     <property name="brokerURL" value="vm://localhost" />   
  14. </bean>   
  15.   
  16. <!-- 使用activemq中的點對點消息模型,隨意指定一個地址 -->   
  17. <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">   
  18.         <constructor-arg value="test/queue"/>    
  19. </bean>   
  20.   
  21. </beans>  


MessageCreator 回調接口經過JmsTemplate中調用代碼提供的Session來建立一條消息。
看一下MessageCreator接口:
Java代碼
 

 

  1. public interface MessageCreator {   
  2.   
  3.     Message createMessage(Session session) throws JMSException;   
  4.   
  5. }   


那麼,咱們來實現發送和接受消息DummyJms類
Java代碼
 

 

  1. public class DummyJms {   
  2.        
  3.     public static void main(String[] args) throws Exception{   
  4.         ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");   
  5.         JmsTemplate jmsTemplate = (JmsTemplate)context.getBean("jmsTemplate");   
  6.         Destination destination = (Destination)context.getBean("destination");   
  7.            
  8.         jmsTemplate.send(destination, new MessageCreator(){   
  9.                    
  10.                 public Message createMessage(Session session)   
  11.                         throws JMSException {   
  12.                     return session.createTextMessage("send message ");   
  13.                 }   
  14.                    
  15.                
  16.         });   
  17.            
  18.         TextMessage msg = (TextMessage)jmsTemplate.receive(destination);   
  19.         System.out.println("receive message = " + msg.getText());   
  20.            
  21.     }   
  22.        
  23. }  


輸出結果:
receive message = send message


但是咱們並無看到的像前文描述的那那些建立消息生產者,消息消費者的一些東西。繼續分析,咱們能夠看一下,
jmsTemplate.send(Destination destination,MessageCreator messageCreator)這裏到底作了什麼,可讓咱們不費吹灰之力,就能夠實現消息的發送。JmsTemplate源代碼:

Java代碼
 

 

  1. public void send(final Destination destination, final MessageCreator messageCreator) throws JmsException {   
  2.         execute(new SessionCallback<Object>() {   
  3.             public Object doInJms(Session session) throws JMSException {   
  4.                 doSend(session, destination, messageCreator);   
  5.                 return null;   
  6.             }   
  7.         }, false);   
  8. }  


JmsTemplate實現了JmsOperations接口,在JmsOperations裏有
Java代碼
 

 

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


的定義。

那麼這個SessionCallback接口是什麼呢?它也爲用戶提供了JMS session。

Java代碼
public interface SessionCallback<T> {   
  1.   
  2.     T doInJms(Session session) throws JMSException;   
  3.   
  4. }  


繼續往下看。doSend方法:

Java代碼
protected void doSend(Session session, Destination destination, MessageCreator messageCreator)   
  1.             throws JMSException {   
  2.   
  3.         Assert.notNull(messageCreator, "MessageCreator must not be null");   
  4.         MessageProducer producer = createProducer(session, destination);   
  5.         try {   
  6.             Message message = messageCreator.createMessage(session);   
  7.             if (logger.isDebugEnabled()) {   
  8.                 logger.debug("Sending created message: " + message);   
  9.             }   
  10.             doSend(producer, message);   
  11.             // Check commit - avoid commit call within a JTA transaction.   
  12.             if (session.getTransacted() && isSessionLocallyTransacted(session)) {   
  13.                 // Transacted session created by this template -> commit.   
  14.                 JmsUtils.commitIfNecessary(session);   
  15.             }   
  16.         }   
  17.         finally {   
  18.             JmsUtils.closeMessageProducer(producer);   
  19.         }   
  20.     }  


createProducer()方法又調用了doCreateProducer(),實際的消息生產者在這裏。
protected MessageProducer doCreateProducer(Session session, Destination destination) throws JMSException {   
  1.         return session.createProducer(destination);   
  2.     }  
在這裏,咱們看到了,spring建立了消息的發送者,關閉鏈接的一些操做。到這裏,你們就明白了,spring內部處理Jms消息的過程了吧(消息的接受也是同樣)。 注:本文使用spring3.0和activemq5.2版本。
相關文章
相關標籤/搜索