贴上JmsTemplate配置,以便理解
Java代码
- <!-- 配置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>
Java代码 下载
- 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
- });
- }
- }
Java代码
- public abstract class JmsDestinationAccessor extends JmsAccessor
- {
- private DestinationResolver destinationResolver;//消息目的地解决器
- private boolean pubSubDomain;//是否为订阅主题模式
- }
Java代码
- 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的内部类
Java代码
- 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
- {
- return JmsTemplate.this.createSession(con);
- }
- public boolean isSynchedLocalTransactionAllowed()
- {
- return isSessionTransacted();
- }
- final JmsTemplate this$0;
- private JmsTemplateResourceFactory()
- {
- this$0 = JmsTemplate.this;
- super();
- }
- }
- }
从JmsTemplate的构造可以看出,主要是初始化事务资源工厂,消息转换器,传输延时,优先级,消息生存时间
再来看发送消息
Java代码
- 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时的情况:
创建连接
Java代码
- conToClose = createConnection();
//JmsAccessor
Java代码
- protected Connection createConnection()
- throws JMSException
- {
- //从ActiveMQConnectionFactory获取连接ActiveMQConnection
- return getConnectionFactory().createConnection();
- }
创建会话
Java代码
- sessionToClose = createSession(conToClose);
Java代码
- protected Session createSession(Connection con)
- throws JMSException
- { 下载
- //从ActiveMQConnection获取连接会话ActiveMQSession
- return con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());
- }
当会话不为空的情况:
//ConnectionFactoryUtils
Java代码
- 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
Java代码
- 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;
- }
- }