Spring + ActiveMQ實現jms傳送訊息
阿新 • • 發佈:2019-02-20
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版本。
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版本。