贴上JmsTemplate配置,以便理解
<!-- 配置Jms模板 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactoryMQ" />
<property name="defaultDestination" ref="testQueue" />
<!-- 接收消息时的超时时间 -->
<!--<property name="receiveTimeout" value="10000" /> -->
<!-- 消息类型转换 -->
<property name="messageConverter" ref="msgConverter"></property>
</bean>
public class JmsTemplate extends JmsDestinationAccessor
implements JmsOperations
{ 下载
public static final long RECEIVE_TIMEOUT_NO_WAIT = -1L;
public static final long RECEIVE_TIMEOUT_INDEFINITE_WAIT = 0L;
private static final Method setDeliveryDelayMethod;
private final JmsTemplateResourceFactory transactionalResourceFactory;
private Object defaultDestination;//消息目的地
private MessageConverter messageConverter;//消息转换器
private boolean messageIdEnabled;
private boolean messageTimestampEnabled;
private boolean pubSubNoLocal;
private long receiveTimeout;
private long deliveryDelay;//传输延时
private boolean explicitQosEnabled;
private int deliveryMode;//消息持久化模式
private int priority;//优先级
private long timeToLive;//消息生存时间
static
{
//获取MessageProducer的设置传输延时方法
setDeliveryDelayMethod = ClassUtils.getMethodIfAvailable(javax/jms/MessageProducer, "setDeliveryDelay", new Class[] {
Long.TYPE
});
}
}
public abstract class JmsDestinationAccessor extends JmsAccessor
{ 下载
private DestinationResolver destinationResolver;//消息目的地解决器
private boolean pubSubDomain;//是否为订阅主题模式
}
public abstract class JmsAccessor
implements InitializingBean
{
private static final Constants sessionConstants = new Constants(javax/jms/Session);
private ConnectionFactory connectionFactory;//连接工厂
private boolean sessionTransacted;//是不是事务会话
private int sessionAcknowledgeMode;//会话确认模式
}
再来看JmsTemplate的构造
Java代码 下载
public JmsTemplate()
{
transactionalResourceFactory = new JmsTemplateResourceFactory();
messageIdEnabled = true;
messageTimestampEnabled = true;
pubSubNoLocal = false;
receiveTimeout = 0L;
deliveryDelay = 0L;
explicitQosEnabled = false;
deliveryMode = 2;
priority = 4;
timeToLive = 0L;
//初始化消息转换器
initDefaultStrategies();
}
protected void initDefaultStrategies()
{
//初始化消息转换器
setMessageConverter(new SimpleMessageConverter());
}
JmsTemplateResourceFactory为JmsTemplate的内部类
public class JmsTemplate extends JmsDestinationAccessor
implements JmsOperations
{
private class JmsTemplateResourceFactory
implements org.springframework.jms.connection.ConnectionFactoryUtils.ResourceFactory
{
public Connection getConnection(JmsResourceHolder holder)
{
return JmsTemplate.this.getConnection(holder);
}
public Session getSession(JmsResourceHolder holder)
{
return JmsTemplate.this.getSession(holder);
}
public Connection createConnection()
throws JMSException
{
return JmsTemplate.this.createConnection();
}
public Session createSession(Connection con)
throws JMSException
{
下载rn JmsTemplate.this.createSession(con);
}
public boolean isSynchedLocalTransactionAllowed()
{
return isSessionTransacted();
}
final JmsTemplate this$0;
private JmsTemplateResourceFactory()
{
this$0 = JmsTemplate.this;
super();
}
}
}
从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;
}
final Destination val$destination;
final MessageCreator val$messageCreator;
final JmsTemplate this$0;
{
this.this$0 = JmsTemplate.this;
destination = destination1;
messageCreator = messagecreator;
super();
}
}, false);
}
再来看执行回调接口
Java代码 下载
public Object execute(SessionCallback action, boolean startConnection)
throws JmsException
{
Connection conToClose;
Session sessionToClose;
Assert.notNull(action, "Callback object must not be null");
conToClose = null;
sessionToClose = null;
Object obj;
try
{
//从ConnectionFactoryUtils获取事务会话
Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(getConnectionFactory(), transactionalResourceFactory, startConnection);
if(sessionToUse == null)
{
//创建连接
conToClose = createConnection();
//创建会话
sessionToClose = createSession(conToClose);
if(startConnection)
conToClose.start();
sessionToUse = sessionToClose;
}
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Executing callback on JMS Session: ").append(sessionToUse).toString());
//执行会话回调接口doInJms方法
obj = action.doInJms(sessionToUse);
}
//关闭会话
JmsUtils.closeSession(sessionToClose);
//释放连接
ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
return obj;
}
先看当会话为null时的情况:
创建连接
conToClose = createConnection();
//JmsAccessor
protected Connection createConnection()
throws JMSException
{
//从ActiveMQConnectionFactory获取连接ActiveMQConnection
return getConnectionFactory().createConnection();
}
创建会话 下载
sessionToClose = createSession(conToClose);
protected Session createSession(Connection con)
throws JMSException
{
//从ActiveMQConnection获取连接会话ActiveMQSession
return con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
当会话不为空的情况:
//ConnectionFactoryUtils
public static Session doGetTransactionalSession(ConnectionFactory connectionFactory, ResourceFactory resourceFactory, boolean startConnection)
throws JMSException
{
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
Assert.notNull(resourceFactory, "ResourceFactory must not be null");
//事务同步管理器获取JmsResourceHolder
JmsResourceHolder resourceHolder = (JmsResourceHolder)TransactionSynchronizationManager.getResource(connectionFactory);
Connection con;
if(resourceHolder != null)
{
//如果JmsResourceHolder存在,则从resourceFactory获取会话
Session session = resourceFactory.getSession(resourceHolder);
if(session != null)
{
if(startConnection)
{
//获取启动,则从resourceFactory获取resourceHolder对应的连接
con = resourceFactory.getConnection(resourceHolder);
if(con != null)
//启动连接
con.start();
}
return session;
}
if(resourceHolder.isFrozen())
return null;
}
if(!TransactionSynchronizationManager.isSynchronizationActive())
return null;
JmsResourceHolder resourceHolderToUse = resourceHolder;
if(resourceHolderToUse == null)
resourceHolderToUse = new JmsResourceHolder(connectionFactory);
//从resourceFactory获取resourceHolder对应的连接
con = resourceFactory.getConnection(resourceHolderToUse);
Session session = null;
try
{
boolean isExistingCon = con != null;
if(!isExistingCon)
{ 下载
con = resourceFactory.createConnection();
resourceHolderToUse.addConnection(con);
}
//resourceFactory根据连接创建会话
session = resourceFactory.createSession(con);
//将连接与会话关系添加到resourceHolderToUse
resourceHolderToUse.addSession(session, con);
if(startConnection)
con.start();
}
if(resourceHolderToUse != resourceHolder)
{
//注册同步器
TransactionSynchronizationManager.registerSynchronization(new JmsResourceSynchronization(resourceHolderToUse, connectionFactory, resourceFactory.isSynchedLocalTransactionAllowed()));
//设置事务
resourceHolderToUse.setSynchronizedWithTransaction(true);
//绑定连接工厂与资源holder的关系
TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
}
return session;
}
来看从事务同步管理器获取JmsResourceHolder
JmsResourceHolder resourceHolder = (JmsResourceHolder)TransactionSynchronizationManager.getResource(connectionFactory);
ublic abstract class TransactionSynchronizationManager
{
private static final ThreadLocal resources = new ThreadLocal();//资源
private static final ThreadLocal synchronizations = new ThreadLocal();//同步器
private static final Comparator synchronizationComparator = new OrderComparator();
private static final ThreadLocal currentTransactionName = new ThreadLocal();//当前事务名
private static final ThreadLocal currentTransactionReadOnly = new ThreadLocal();//事务读写
private static final ThreadLocal currentTransactionIsolationLevel = new ThreadLocal();事务级别
private static final ThreadLocal actualTransactionActive = new ThreadLocal();
public static Object getResource(Object key)
{
Assert.notNull(key, "Key must not be null");
Map map = (Map)resources.get();
if(map == null)
return null;
Object value = map.get(key);
if(value != null && logger.isDebugEnabled())
logger.debug("Retrieved value [" + value + "] for key [" + key + "] bound to thread [" + Thread.currentThread().getName() + "]");
return value;
}
}