/**
* Send the given JMS message.
* @param session the JMS Session to operate on
* @param destination the JMS Destination to send to
* @param messageCreator callback to create a JMS Message
* @throws JMSException if thrown by JMS API methods
*/
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);
}
}
public void convertAndSend(
Destination destination, final Object message, final MessagePostProcessor postProcessor)
throws JmsException {
send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
Message msg = getRequiredMessageConverter().toMessage(message, session);
return postProcessor.postProcessMessage(msg);//注意这里不是对消息发送的后置处理,而是对消息Converter的后置处理(消息发送前的一个Hook)
}
});
}
/**
* Actually receive a JMS message.
* @param session the JMS Session to operate on
* @param consumer the JMS MessageConsumer to receive with
* @return the JMS Message received, or {@code null} if none
* @throws JMSException if thrown by JMS API methods
*/
protected Message doReceive(Session session, MessageConsumer consumer) throws JMSException {
try {
// Use transaction timeout (if available).
long timeout = getReceiveTimeout();
JmsResourceHolder resourceHolder =
(JmsResourceHolder) TransactionSynchronizationManager.getResource(getConnectionFactory());
if (resourceHolder != null && resourceHolder.hasTimeout()) {
timeout = Math.min(timeout, resourceHolder.getTimeToLiveInMillis());
}
Message message = doReceive(consumer, timeout);
if (session.getTransacted()) {
// Commit necessary - but avoid commit call within a JTA transaction.
if (isSessionLocallyTransacted(session)) {
// Transacted session created by this template -> commit.
JmsUtils.commitIfNecessary(session);
}
}
else if (isClientAcknowledge(session)) {
// Manually acknowledge message, if any.
if (message != null) {
message.acknowledge();
}
}
return message;
}
finally {
JmsUtils.closeMessageConsumer(consumer);
}
}
关键代码处已经有注释了,这里就不再赘述了,掌握了这几个核心方法,这个类就算拿下了。
恩,从编程API的角度来看,差不多就这些内容了。
第二部分:包结构
下面,我们从包结构的角度再来进一步了解一下Spring对Jms的集成,如下图:

org.springframework.jms包里面提供了一些JMS规范异常的runtime版本,看看jms2在这方面的改进,就知道spring在这方面已然是先驱了。
org.springframework.jms.config包里面放置了对Jms schema的解析,这是spring为我们提供的一个非常有用的特性,schema用的好的话,也可以做到面向接口编程,扩展性极好。这方面感兴趣的同学,推荐阅读这里http://openwebx.org/docs/Webx3_Gui