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;
}
/**
* 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);
}
}
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);
}
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); }返回的。
转载于:https://blog.51cto.com/zorro/831986