Spring与ActiveMQ的集成详解

贴上JmsTemplate配置,以便理解 

Java代码 

 收藏代码

  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代码 下载

 收藏代码

  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代码 

 收藏代码

  1. public abstract class JmsDestinationAccessor extends JmsAccessor  
  2. {  
  3.     private DestinationResolver destinationResolver;//消息目的地解决器  
  4.     private boolean pubSubDomain;//是否为订阅主题模式  
  5. }  

 

Java代码 

 收藏代码

  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代码 

 收藏代码

  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代码 

 收藏代码

  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.         {  
  23.             return JmsTemplate.this.createSession(con);  
  24.         }  
  25.         public boolean isSynchedLocalTransactionAllowed()  
  26.         {  
  27.             return isSessionTransacted();  
  28.         }  
  29.         final JmsTemplate this$0;  
  30.         private JmsTemplateResourceFactory()  
  31.         {  
  32.             this$0 = JmsTemplate.this;  
  33.             super();  
  34.         }  
  35.     }  
  36. }  


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

Java代码 

 收藏代码

  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代码 

 收藏代码

  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代码 

 收藏代码

  1. conToClose = createConnection();  


//JmsAccessor 

Java代码 

 收藏代码

  1. protected Connection createConnection()  
  2.         throws JMSException  
  3.     {  
  4.         //从ActiveMQConnectionFactory获取连接ActiveMQConnection  
  5.         return getConnectionFactory().createConnection();  
  6.     }  


创建会话 

Java代码 

 收藏代码

  1. sessionToClose = createSession(conToClose);  

 

Java代码 

 收藏代码

  1. protected Session createSession(Connection con)  
  2.         throws JMSException  
  3.     {  下载
  4.         //从ActiveMQConnection获取连接会话ActiveMQSession  
  5.         return con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());  
  6.     }  


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

Java代码 

 收藏代码

  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代码 

 收藏代码

  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. }  

转载于:https://my.oschina.net/u/3196938/blog/817550

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值