http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-mdp
Spring JMS API
Org.springframework.jms.core.JmsTemplate
java.lang.Object
org.springframework.jms.support.JmsAccessor
org.springframework.jms.support.destination.JmsDestinationAccessor org.springframework.jms.core.JmsTemplate
Interfaces:
InitializingBean, JmsOperations
默认的模板策略:DynamicDestinationResolver and SimpleMessageConverter
默认的消息转换器SimpleMessageConverter,能够操作BytesMessage,TextMessages和ObjectMessages,可以通过setMessageConverter设置。
SetReceiveTimeout:
设置接收操作的超时时间(微秒),默认是RECEIVE_TIMEOUT_INDEFINITE_WAIT,接收操作不超时;也可以设置为RECEIVE_TIMEOUT_NO_WAIT表示不阻塞,检查是否由立即可用的消息;
设置是否QOS(deliveryMode,priority,timeToLive)在发送消息时可用;
从默认的destination同步获取消息,只等待特定的时间。该方法会阻塞线程直到消息可用或超时。
DefaultMessageListenerContainer
Message listener container variant that uses plain JMS client APIs, specifically a loop ofMessageConsumer.receive()
Jms
JmsTemplate用于消息产生和同步消息接收。异步消息接收类似于J2EE的message-driven bean风格,Spring提供了一些消息监听容器来创建消息驱动POJO(MDPs)。JmsTemplate向用户暴露了JMS session和消息生产者。
org.springframework.jms.core提供了使用JMS的核心功能。通过提供JMS的模板类创建和释放资源来简化JMS的操作,类似于JdbcTemplate于JDBC。
org.springframework.jms.support提供了JMSException解释机制;
org.springframework.jms.support.converter提供了MessageConverter用于Java对象和JMS消息转换;
org.springframework.jms.support.destination提供了多种策略用于管理JMS的destination,例如查找JNDI中destination的service locator;
org.springframework.jms.connection实现了独立应用的ConnectionFactory;同时也包含了Spring平台的JmsTransactionManager实现,可以将JMS作为一个事务资源集成到Spring的事务管理机制中。
JmsTemplate
JmsTemplate主要通过实现回调接口来使用。
MessageCreator通过给定Session来创建消息;
为了实现JMS API更复杂的操作,SessionCallback和ProducerCallback给用户暴露了Session和MessageProducer。
JMS API提供了两种消息发送方法,一种带有delivery mode, 优先级和time-to-live作为QOS参数,一种不带QOS参数,使用默认值。JmsTemplate提供了多种发送方法,为了避免重复设置,QOS参数作为bean的属性暴露。同样的接收调用的超时时间也通过setReceiveTimeout进行设置。
一些JMS provider允许在ConnectionFactory的配置中设置默认的QOS值,会导致MessageProducer的send方法使用与JMS指定的QOS默认值不同的值。为了提供一致的QOS操作,JmsTemplate通过将isExplicitQosEnabled设为true来使用自己的QOS。
JmsTemplate实例是线程安全的,因此可以将一个实例注入到多个依赖的协作者中。JmsTemplate维护了一个指向ConnectionFactory的引用。
Connections
Spring提供了一个ConnectionFactory接口的实现:SingleConnectionFactory,会返回和createConnection同样的结果,且不需要调用close。
Destination Management
Spring提供了JndiObjectFactoryBean向JMS destinations注入对象。但在应用程序中需要大量的destination时,或者JMS provider有更高级的destination管理操作时会很麻烦。例如当需要动态生成destination或提供多层的destination命名空间。DynamicDestinationResolver是msTemplate默认的实现动态destination。同时提供了JndiDestinationResolver。(我了个去,这一段完全不知所云)
一个简单的实现是使用TopicSession方法的createTopic或QueueSession的createQueue方法来创建默认参数的destination。
pubSubDomain使用来配置JMS域。默认false,表示是PTP域Queue。
也可以通过配置JmsTemplate使用默认的destination,通过属性defaultDestination。defaultDestination的发送和接收操作不指向具体的目的地。
Message Listener Containers
消息监听容器从消息队列中接收消息并调用MessageListener。
消息监听容器是MDP和消息提供者的中介。允许开发者关注自己的与消息相关业务逻辑实现,而把消息的监听交给框架。有三类消息容器:SimpleMessageListenerContainer,DefaultMessageListenerContainer,ServerSessionMessageListenerContainer。
Transaction management
Spring提供了JmsTransactionManager来为单个ConnectionFactory管理事务。
Spring提供了SingleConnectionFactory来提供共享的JMS Connection,每个事务有自己独立的Session。此外,也可以使用提供者特有的pooling适配器。
JmsTemplate使用JtaTransactionManager和XA-capable JMS ConnectionFactory来实现分布式事务。(需要使用JTA事务管理和XA配置的ConnectionFactory)。
当在unmanaged环境中使用JmsTemplate,需要使用SessionTransacted和sessionAcknowledgeMode来指定事务的值。当JmsTemplate使用PlatformTransactonManager时,模板会被给予一个事务化的JMS Session。
Message Converters
用来进行Java对象和消息之间的转换,在convertAndSend和receiveAndConvert中实现接口MessageConverter。SimpleMessageConverter是默认的实现,支持String和TextMessage,byte[]和BytesMessage,Map和MapMessage之间转换。
此外,MessagePostProcessor提供了在消息发送钱和转换后对消息属性和头的操作。
如果需要对Session或MessageProducer做进一步操作,可使用SessionCallback和ProducerCallback,通过execute方法执行。
异步消息接收——Message-Driven POJOs
通过实现javax.jms.MessageListener接口。在这种情况下,你的POJO是多线程的几首消息,所以必须保证实现是线程安全的。
当需要在MDP中对接收到的消息进行响应,则可使用SessionAwareMessageListener接口。注意每个消息处理方法的参数必须严格与Message类型对应。
MessageListenerAdapter
通过配置,可以让你的任何类暴露为一个MDP。
public interface MessageDelegate {
void handleMessage(String message); void handleMessage(Map message); void handleMessage(byte[] message); void handleMessage(Serializable message); } public class DefaultMessageDelegate implements MessageDelegate { // implementation elided for clarity... } <!-- this is the Message Driven POJO (MDP) --> <bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"> <constructor-arg> <bean class="jmsexample.DefaultMessageDelegate"/> </constructor-arg> </bean> <!-- and this is the message listener container... --> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory"/> <property name="destination" ref="destination"/> <property name="messageListener" ref="messageListener" /> </bean>
此外还有另一种实现方法:
public interface TextMessageDelegate { void receive(TextMessage message); } public class DefaultTextMessageDelegate implements TextMessageDelegate { // implementation elided for clarity... }
配置:
<bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"> <constructor-arg> <bean class="jmsexample.DefaultTextMessageDelegate"/> </constructor-arg> <property name="defaultListenerMethod" value="receive"/> <!-- we don't want automatic message context extraction --> <property name="messageConverter"> <null/> </property> </bean> 在该实现中,若接收到消息不是TextMessage类型,则会抛出IllegalStateException。 如果消息处理函数返回值不是void,MessageListenerAdapter还可以自动发送响应消息。返回值会发送给JMS的Reply-To属性定义的Destination,或者是MessageListenerAdapter中配置的默认的Destination。 Transaction JCA Message Endpoints
JMS namespace
主要包括了<listener-container/>和<jca-listener-container/>,每一个都有多个<listener/>子元素。