1. 程式人生 > >Spring + ActiveMQ實現jms傳送訊息

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的封裝:

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

}

所以,我們有兩種方式注入ConnectionFactory,本文我們採用構造方法的方式。

spring_jms.xml






















MessageCreator 回撥介面通過JmsTemplate中呼叫程式碼提供的Session來建立一條訊息。
看一下MessageCreator介面:

public interface MessageCreator {

    Message createMessage(Session session) throws JMSException;




那麼,我們來實現傳送和接受訊息DummyJms類

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原始碼:


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


JmsTemplate實現了JmsOperations介面,在JmsOperations裡有

T execute(SessionCallback action) throws JmsException;


的定義。

那麼這個SessionCallback介面是什麼呢?它也為使用者提供了JMS session。


public interface SessionCallback {

    T doInJms(Session session) throws JMSException;

}


繼續往下看。doSend方法:


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(),實際的訊息生產者在這裡。

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


在這裡,我們看到了,spring建立了訊息的傳送者,關閉連線的一些操作。到這裡,大家就明白了,spring內部處理Jms訊息的過程了吧(訊息的接受也是一樣)。
注:本文使用spring3.0和activemq5.2版本。