Spring 对 JMS 的支持
Srping 在 org.springframework.jsm 包中提供了一个用于简化 JMS API 的使用的抽象框架 , 并对用户屏蔽了 JMS1.1 与 JMS1.02 之间的差别
Spring JMS API
org.springframework.jms.core JMS 模板类 执行公共操作 使用接口回调 发送接收消息
org.springframework.jms 为 JMS 提供的运行期异常体系
org.springframework.jms.support 提供异常转化器 , 将 JMS 检查异常映射到该异常体系
org.springframework.jsm.support.conver 消息转化器 , 以便将 POJO 转化为 JMS 消息 , 提供 MDP 的功能
org.springframework.jms.listener 消息监听器容器 , 提供了异步消息接收的支持
org.springframework.jsm.support.destination 提供地址解析的功能 , 允许用户使用字符串的形式指定消息发送或接收地址 , 地址解析器负责地址的解析
org.springframework.jms.connection 提供一个 ConnectionFactory 的实现 , 还为 JMS 提供了一个 Spring 的 PlatformTransactionManager 的实现 ,JmsTaransactionManager , 这样 JMS 作为一个事务资源无缝集成到 Spring 的事务管理机制中
JMS 模板类
JMSTemplate 的使用情况对于两种消息域类型是一致的
JMSTemplate102
JMSTemplate102 通过指定 pubSubDomain 属性指定消息类型 true Pub/Sub
<bean id=”jsmTempalte” class=”org.springframewrok.jms.core.JmsTempalte”>
<property name=”pubSubDomain” value=”true”/>
</bean>
JmsTemplate102 的 ConnectionFactory 类型必须 JMSTemplate 的消息类型一致
如果 JmsTempalte 的消息类型为 pubSubDomain=true, 则 ConnectionFactory 必须是
javax.jms.TopicConnectionFactory, 如果是 false, 就使用 javax.jms.QueueConnectionFactory
因为 PooledConnectionFactory 只实现的 ConnectionFactory 接口 , 所以最好的办法是使用
ActiveMQConnectionFactory, 因为它同时实现了 ConnectionFactory,TopicConnectionFactory,
QueueConnectionFactory 接口 , 或者使用 JNDI 中的 ConnectionFactory , 开发中尽量使用后者
JmsTemplate 的支持类 org.springframework.jms.core.JmsGatewaySupport , 只要向该类注入一个
ConnectionFactory , 它会自动创建 JmsTempalte 实例
JMS 的异常映射
JMS 检查型异常转为运行时异常
Org.srpingframework.jms 包中的异常为 javax.jms 异常提供了类型转转换的镜像实现 ,Spring 中的 JMS 异常都继承于 JmsException
除此之外 ,Spring 还提供了一些特定的 JMS 异常
DestinationResolutionException 在 DestinationResolver 解析消息地址是发生错误抛出的异常
SynchedLocalTransactionFailedExcetion 在同步本地事务发生异常抛出的异常 , 事务结束再次同步就会有这样的异常抛出
UncategorizedJmsException 所有归类的异常
JMS 声明事务时可以在事务控制策略中使用这些异常
使用回调接口发送 / 接收消息
MessageSender.java
package cn.com.snt.spring_jms;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.support.JmsGatewaySupport;
public class MessageSender extends JmsGatewaySupport {
public void sendTextMsg( final String textMsg){
getJmsTemplate().send( new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(textMsg);
}
});
}
}
applicationContext-sender.xml
<? xml version = "1.0" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:amq = "http://activemq.org/config/1.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd" >
< bean id = "connectionFactory" class = "org.apache.activemq.pool.PooledConnectionFactory" >
< property name = "connectionFactory" >
< bean class = "org.apache.activemq.ActiveMQConnectionFactory" >
< property name = "brokerURL" value = "tcp://localhost:61616" />
</ bean >
</ property >
</ bean >
< bean id = "dest" class = "org.apache.activemq.command.ActiveMQQueue" >
< constructor-arg value = "myDest" />
</ bean >
< bean id = "jmsTemplate" class = "org.springframework.jms.core.JmsTemplate" >
< property name = "connectionFactory" ref = "connectionFactory" />
< property name = "defaultDestination" ref = "dest" />
</ bean >
< bean id = "messageSender" class = "cn.com.snt.spring_jms.MessageSender" >
< property name = "jmsTemplate" ref = "jmsTemplate" />
</ bean >
</ beans >
MessageReceiver.java
package cn.com.snt.spring_jms;
import javax.jms.JMSException;
import javax.jms.TextMessage;
import org.springframework.jms.core.support.JmsGatewaySupport;
public class MessageReceiver extends JmsGatewaySupport {
public void receiveTextMsg(){
TextMessage textMsg=(TextMessage)getJmsTemplate().receive();
try {
System. out .println( "msgid:" +textMsg.getJMSMessageID());
System. out .println( "msg:" +textMsg.getText());
} catch (JMSException e){
e.printStackTrace();
}
}
}
applicationContext-receiver.xml
<? xml version = "1.0" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:amq = "http://activemq.org/config/1.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd" >
< bean id = "connectionFactory"
class = "org.apache.activemq.pool.PooledConnectionFactory" >
< property name = "connectionFactory" >
< bean
class = "org.apache.activemq.ActiveMQConnectionFactory" >
< property name = "brokerURL"
value = "tcp://localhost:61616" />
</ bean >
</ property >
</ bean >
< bean id = "dest" class = "org.apache.activemq.command.ActiveMQQueue" >
< constructor-arg value = "myDest" />
</ bean >
< bean id = "jmsTemplate"
class = "org.springframework.jms.core.JmsTemplate" >
< property name = "connectionFactory" ref = "connectionFactory" />
< property name = "defaultDestination" ref = "dest" />
</ bean >
< bean id = "messageReceiver" class = "cn.com.snt.spring_jms.MessageReceiver" >
< property name = "jmsTemplate" ref = "jmsTemplate" />
</ bean >
</ beans >
JmsTemplate send 方法有三种重载
send(MessageCreator messageCreator) 使用该方法一定要通过 defaultDestination 或
defaultDestinationName 指定默认地址 , 否则会报异常
send(Destination dest,MessageCreator messageCreator) 发送消息到指定目的地址
send(String destinationName,String messageSelector ) 将消息发送到 DestinationResolver 解析 destinationName 得到的真实地址 , 默认采用 DynamicDestinationResolver 解析地址
DestinationResoler 接口只有一个方法
Destination resolveDestinationName(Session session,String destintaionName,boolean pubSubDomain)
pubSubDomain=true 解析为 Topic , 否则解析为 Queue