贴上JmsTemplate配置,以便理解 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. <!-- 配置Jms模板  -->    

  2. <bean id="jmsQueueTemplate"  class="org.springframework.jms.core.JmsTemplate">    

  3.            <property name="connectionFactory" ref="connectionFactoryMQ" />    

  4.            <property name="defaultDestination" ref="testQueue" />    

  5.            <!-- 接收消息时的超时时间 -->  

  6.            <!--<property name="receiveTimeout" value="10000" />  -->   

  7.            <!-- 消息类型转换 -->    

  8.         <property name="messageConverter" ref="msgConverter"></property>    

  9. </bean>   



Java代码   Spring与ActiveMQ的集成详解_mybatis

  1.  public class JmsTemplate extends JmsDestinationAccessor  

  2.     implements JmsOperations  

  3. {  下载

  4.     public static final long RECEIVE_TIMEOUT_NO_WAIT = -1L;  

  5.     public static final long RECEIVE_TIMEOUT_INDEFINITE_WAIT = 0L;  

  6.     private static final Method setDeliveryDelayMethod;  

  7.     private final JmsTemplateResourceFactory transactionalResourceFactory;  

  8.     private Object defaultDestination;//消息目的地   

  9.     private MessageConverter messageConverter;//消息转换器  

  10.     private boolean messageIdEnabled;  

  11.     private boolean messageTimestampEnabled;  

  12.     private boolean pubSubNoLocal;  

  13.     private long receiveTimeout;  

  14.     private long deliveryDelay;//传输延时  

  15.     private boolean explicitQosEnabled;  

  16.     private int deliveryMode;//消息持久化模式  

  17.     private int priority;//优先级  

  18.     private long timeToLive;//消息生存时间  

  19.     static   

  20.     {  

  21.        //获取MessageProducer的设置传输延时方法  

  22.         setDeliveryDelayMethod = ClassUtils.getMethodIfAvailable(javax/jms/MessageProducer, "setDeliveryDelay"new Class[] {  

  23.             Long.TYPE  

  24.         });  

  25.     }  

  26. }  


Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. public abstract class JmsDestinationAccessor extends JmsAccessor  

  2. {  下载

  3.     private DestinationResolver destinationResolver;//消息目的地解决器  

  4.     private boolean pubSubDomain;//是否为订阅主题模式  

  5. }  


Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. public abstract class JmsAccessor  

  2.     implements InitializingBean  

  3. {  

  4.     private static final Constants sessionConstants = new Constants(javax/jms/Session);  

  5.     private ConnectionFactory connectionFactory;//连接工厂  

  6.     private boolean sessionTransacted;//是不是事务会话  

  7.     private int sessionAcknowledgeMode;//会话确认模式  

  8.   

  9. }  


再来看JmsTemplate的构造 

Java代码 下载 Spring与ActiveMQ的集成详解_mybatis

  1. public JmsTemplate()  

  2.     {  

  3.         transactionalResourceFactory = new JmsTemplateResourceFactory();  

  4.         messageIdEnabled = true;  

  5.         messageTimestampEnabled = true;  

  6.         pubSubNoLocal = false;  

  7.         receiveTimeout = 0L;  

  8.         deliveryDelay = 0L;  

  9.         explicitQosEnabled = false;  

  10.         deliveryMode = 2;  

  11.         priority = 4;  

  12.         timeToLive = 0L;  

  13.     //初始化消息转换器  

  14.         initDefaultStrategies();  

  15.     }  

  16.     protected void initDefaultStrategies()  

  17.     {  

  18.         //初始化消息转换器  

  19.         setMessageConverter(new SimpleMessageConverter());  

  20.     }  



JmsTemplateResourceFactory为JmsTemplate的内部类 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1.  public class JmsTemplate extends JmsDestinationAccessor  

  2.     implements JmsOperations  

  3. {  

  4.     private class JmsTemplateResourceFactory  

  5.         implements org.springframework.jms.connection.ConnectionFactoryUtils.ResourceFactory  

  6.     {  

  7.         public Connection getConnection(JmsResourceHolder holder)  

  8.         {  

  9.             return JmsTemplate.this.getConnection(holder);  

  10.         }  

  11.         public Session getSession(JmsResourceHolder holder)  

  12.         {  

  13.             return JmsTemplate.this.getSession(holder);  

  14.         }  

  15.         public Connection createConnection()  

  16.             throws JMSException  

  17.         {  

  18.             return JmsTemplate.this.createConnection();  

  19.         }  

  20.         public Session createSession(Connection con)  

  21.             throws JMSException  

  22.         {  

    下载

    rn JmsTemplate.this.createSession(con);  

  23.         }  

  24.         public boolean isSynchedLocalTransactionAllowed()  

  25.         {  

  26.             return isSessionTransacted();  

  27.         }  

  28.         final JmsTemplate this$0;  

  29.         private JmsTemplateResourceFactory()  

  30.         {  

  31.             this$0 = JmsTemplate.this;  

  32.             super();  

  33.         }  

  34.     }  

  35. }  


从JmsTemplate的构造可以看出,主要是初始化事务资源工厂,消息转换器,传输延时,优先级,消息生存时间 
再来看发送消息 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. public void send(final Destination destination, final MessageCreator messageCreator)  

  2.         throws JmsException  

  3.     {  

  4.         //创建会话回调接口,发送消息  

  5.         execute(new SessionCallback() {  

  6.   

  7.             public Object doInJms(Session session)  

  8.                 throws JMSException  

  9.             {  

  10.             //会话发送消息  

  11.                 doSend(session, destination, messageCreator);  

  12.                 return null;  

  13.             }  

  14.   

  15.             final Destination val$destination;  

  16.             final MessageCreator val$messageCreator;  

  17.             final JmsTemplate this$0;  

  18.   

  19.               

  20.             {  

  21.                 this.this$0 = JmsTemplate.this;  

  22.                 destination = destination1;  

  23.                 messageCreator = messagecreator;  

  24.                 super();  

  25.             }  

  26.         }, false);  

  27.     }  


再来看执行回调接口 

Java代码 下载 Spring与ActiveMQ的集成详解_mybatis

  1. public Object execute(SessionCallback action, boolean startConnection)  

  2.         throws JmsException  

  3.     {  

  4.         Connection conToClose;  

  5.         Session sessionToClose;  

  6.         Assert.notNull(action, "Callback object must not be null");  

  7.         conToClose = null;  

  8.         sessionToClose = null;  

  9.         Object obj;  

  10.         try  

  11.         {  

  12.         //从ConnectionFactoryUtils获取事务会话  

  13.             Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(getConnectionFactory(), transactionalResourceFactory, startConnection);  

  14.             if(sessionToUse == null)  

  15.             {  

  16.             //创建连接  

  17.                 conToClose = createConnection();  

  18.         //创建会话  

  19.                 sessionToClose = createSession(conToClose);  

  20.                 if(startConnection)  

  21.                     conToClose.start();  

  22.                 sessionToUse = sessionToClose;  

  23.             }  

  24.             if(logger.isDebugEnabled())  

  25.                 logger.debug((new StringBuilder()).append("Executing callback on JMS Session: ").append(sessionToUse).toString());  

  26.             //执行会话回调接口doInJms方法  

  27.         obj = action.doInJms(sessionToUse);  

  28.         }  

  29.        //关闭会话  

  30.         JmsUtils.closeSession(sessionToClose);  

  31.     //释放连接  

  32.         ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);  

  33.         return obj;  

  34.     }  



先看当会话为null时的情况: 
创建连接 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. conToClose = createConnection();  


//JmsAccessor 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. protected Connection createConnection()  

  2.         throws JMSException  

  3.     {  

  4.         //从ActiveMQConnectionFactory获取连接ActiveMQConnection  

  5.         return getConnectionFactory().createConnection();  

  6.     }  


创建会话 下载

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. sessionToClose = createSession(conToClose);  


Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. protected Session createSession(Connection con)  

  2.         throws JMSException  

  3.     {  

  4.         //从ActiveMQConnection获取连接会话ActiveMQSession  

  5.         return con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());  

  6.     }  


当会话不为空的情况: 
//ConnectionFactoryUtils 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. public static Session doGetTransactionalSession(ConnectionFactory connectionFactory, ResourceFactory resourceFactory, boolean startConnection)  

  2.        throws JMSException  

  3.    {  

  4.        Assert.notNull(connectionFactory, "ConnectionFactory must not be null");  

  5.        Assert.notNull(resourceFactory, "ResourceFactory must not be null");  

  6. //事务同步管理器获取JmsResourceHolder  

  7.        JmsResourceHolder resourceHolder = (JmsResourceHolder)TransactionSynchronizationManager.getResource(connectionFactory);  

  8.        Connection con;  

  9.        if(resourceHolder != null)  

  10.        {  

  11.     //如果JmsResourceHolder存在,则从resourceFactory获取会话  

  12.            Session session = resourceFactory.getSession(resourceHolder);  

  13.            if(session != null)  

  14.            {  

  15.                if(startConnection)  

  16.                {  

  17.         //获取启动,则从resourceFactory获取resourceHolder对应的连接  

  18.                    con = resourceFactory.getConnection(resourceHolder);  

  19.                    if(con != null)  

  20.             //启动连接  

  21.                        con.start();  

  22.                }  

  23.                return session;  

  24.            }  

  25.            if(resourceHolder.isFrozen())  

  26.                return null;  

  27.        }  

  28.        if(!TransactionSynchronizationManager.isSynchronizationActive())  

  29.            return null;  

  30.        JmsResourceHolder resourceHolderToUse = resourceHolder;  

  31.        if(resourceHolderToUse == null)  

  32.            resourceHolderToUse = new JmsResourceHolder(connectionFactory);  

  33. //从resourceFactory获取resourceHolder对应的连接  

  34.        con = resourceFactory.getConnection(resourceHolderToUse);  

  35.        Session session = null;  

  36.        try  

  37.        {  

  38.            boolean isExistingCon = con != null;  

  39.            if(!isExistingCon)  

  40.            {  下载

  41.                con = resourceFactory.createConnection();  

  42.                resourceHolderToUse.addConnection(con);  

  43.            }  

  44.     //resourceFactory根据连接创建会话  

  45.            session = resourceFactory.createSession(con);  

  46.     //将连接与会话关系添加到resourceHolderToUse  

  47.            resourceHolderToUse.addSession(session, con);  

  48.            if(startConnection)  

  49.                con.start();  

  50.        }  

  51.        if(resourceHolderToUse != resourceHolder)  

  52.        {  

  53.     //注册同步器  

  54.            TransactionSynchronizationManager.registerSynchronization(new JmsResourceSynchronization(resourceHolderToUse, connectionFactory, resourceFactory.isSynchedLocalTransactionAllowed()));  

  55.            //设置事务  

  56.     resourceHolderToUse.setSynchronizedWithTransaction(true);  

  57.     //绑定连接工厂与资源holder的关系  

  58.            TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);  

  59.        }  

  60.        return session;  

  61.    }  


来看从事务同步管理器获取JmsResourceHolder 

Java代码  Spring与ActiveMQ的集成详解_mybatis

  1. JmsResourceHolder resourceHolder = (JmsResourceHolder)TransactionSynchronizationManager.getResource(connectionFactory);  

  2. ublic abstract class TransactionSynchronizationManager  

  3. {  

  4.     private static final ThreadLocal resources = new ThreadLocal();//资源  

  5.     private static final ThreadLocal synchronizations = new ThreadLocal();//同步器  

  6.     private static final Comparator synchronizationComparator = new OrderComparator();  

  7.     private static final ThreadLocal currentTransactionName = new ThreadLocal();//当前事务名  

  8.     private static final ThreadLocal currentTransactionReadOnly = new ThreadLocal();//事务读写  

  9.     private static final ThreadLocal currentTransactionIsolationLevel = new ThreadLocal();事务级别  

  10.     private static final ThreadLocal actualTransactionActive = new ThreadLocal();  

  11.     public static Object getResource(Object key)  

  12.     {  

  13.         Assert.notNull(key, "Key must not be null");  

  14.         Map map = (Map)resources.get();  

  15.         if(map == null)  

  16.             return null;  

  17.         Object value = map.get(key);  

  18.         if(value != null && logger.isDebugEnabled())  

  19.             logger.debug("Retrieved value [" + value + "] for key [" + key + "] bound to thread [" + Thread.currentThread().getName() + "]");  

  20.         return value;  

  21.     }  

  22. }