MOM系列文章之 - Spring Jms Integration 解读(二)

2014-11-24 07:36:59 · 作者: · 浏览: 3
onFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection); } }

/**
	 * 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