Spring JmsTemplate的设计与实现解析

Spring中JmsTemplate通过包装Producer/Sender中的Send方法以及Subscriber/Consumer中的receive方法,接管了在发送过程中涉及到的Connection和Session的创建以及与JMS提供者之间连接。这里涉及到SessionCallback与JmsTemplate的关系。SessionCallback是定义在org.springframework.jms.core中的一个接口,里面只定义了一个方法 Object doInJms(Session session) throws JMSException.
public interface SessionCallback {

   /**
    * Execute any number of operations against the supplied JMS
    * {@link Session}, possibly returning a result.
    * @param session the JMS <code>Session</code>
    * @return a result object from working with the <code>Session</code>, if any (so can be <code>null</code>)    
    * @throws javax.jms.JMSException if thrown by JMS API methods
    */
  Object doInJms(Session session) throws JMSException;

}
而在JmsTemplate中定义了一个叫做Object execute(SessionCallback action) throws JMSException的方法,而这个方法又调用Object execute(SessionCallback action,boolean startCon) throws JMSException,这个方法中定义的逻辑如下,
public Object execute(SessionCallback action, boolean startConnection) throws JmsException {
    Assert.notNull(action, "Callback object must not be null");
    Connection conToClose = null;
    Session sessionToClose = null;
     try {
      Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
          getConnectionFactory(), this.transactionalResourceFactory, startConnection);
       if (sessionToUse == null) {
        conToClose = createConnection();
        sessionToClose = createSession(conToClose);
         if (startConnection) {
          conToClose.start();
        }
        sessionToUse = sessionToClose;
      }
       if (logger.isDebugEnabled()) {
        logger.debug( "Executing callback on JMS Session: " + sessionToUse);
      }
       return action.doInJms(sessionToUse);
    }
     catch (JMSException ex) {
       throw convertJmsAccessException(ex);
    }
     finally {
      JmsUtils.closeSession(sessionToClose);
      ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
    }
  }
主要是为send()和receive()方法准备必备的Connection和Session的连接,每次调用send()/receive()方法时都会先调用这个execute()方法:
public void send(MessageCreator messageCreator) throws JmsException {
    Destination defaultDestination = getDefaultDestination();
     if (defaultDestination != null) {
      send(defaultDestination, messageCreator);
    }
     else {
      send(getRequiredDefaultDestinationName(), messageCreator);
    }
  }

   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;
      }
    }, false);
  }
在 send(final Destination destination, final MessageCreator messageCreator) throws JmsException方法中调用execute()方法时传入了一个匿名类,该匿名类实现了SessionCallback接口并覆盖了doInJms()方法,这个方法将包含真正的逻辑,通过execute(){... return action.doInJms(sessionToUse); }返回的。

你可能感兴趣的:(jmstemplate,JmsTemplate解析)