Release shared JMS Connection on Single/CachingConnectionFactory.stop()

See gh-30612
This commit is contained in:
Juergen Hoeller
2023-06-07 18:40:56 +02:00
parent 1b62b6dd89
commit 759ab23c45
2 changed files with 116 additions and 47 deletions

View File

@@ -40,6 +40,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.Lifecycle;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -85,7 +86,7 @@ import org.springframework.util.ObjectUtils;
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setCacheLevel
*/
public class SingleConnectionFactory implements ConnectionFactory, QueueConnectionFactory,
TopicConnectionFactory, ExceptionListener, InitializingBean, DisposableBean {
TopicConnectionFactory, ExceptionListener, InitializingBean, DisposableBean, Lifecycle {
protected final Log logger = LogFactory.getLog(getClass());
@@ -330,6 +331,67 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
}
}
/**
* Exception listener callback that renews the underlying single Connection.
* @see #resetConnection()
*/
@Override
public void onException(JMSException ex) {
logger.info("Encountered a JMSException - resetting the underlying JMS Connection", ex);
resetConnection();
}
/**
* Close the underlying shared connection.
* The provider of this ConnectionFactory needs to care for proper shutdown.
* <p>As this bean implements DisposableBean, a bean factory will
* automatically invoke this on destruction of its cached singletons.
* @see #resetConnection()
*/
@Override
public void destroy() {
resetConnection();
}
/**
* Initialize the underlying shared connection on start.
* @since 6.1
* @see #initConnection()
*/
@Override
public void start() {
try {
initConnection();
}
catch (JMSException ex) {
logger.info("Start attempt failed for shared JMS Connection", ex);
}
}
/**
* Reset the underlying shared connection on stop.
* @since 6.1
* @see #resetConnection()
*/
@Override
public void stop() {
resetConnection();
}
/**
* Check whether there is currently an underlying connection.
* @since 6.1
* @see #start()
* @see #stop()
*/
@Override
public boolean isRunning() {
synchronized (this.connectionMonitor) {
return (this.connection != null);
}
}
/**
* Initialize the underlying shared Connection.
* <p>Closes and reinitializes the Connection if an underlying
@@ -375,41 +437,6 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
}
}
/**
* Exception listener callback that renews the underlying single Connection.
* @see #resetConnection()
*/
@Override
public void onException(JMSException ex) {
logger.info("Encountered a JMSException - resetting the underlying JMS Connection", ex);
resetConnection();
}
/**
* Close the underlying shared connection.
* The provider of this ConnectionFactory needs to care for proper shutdown.
* <p>As this bean implements DisposableBean, a bean factory will
* automatically invoke this on destruction of its cached singletons.
* @see #resetConnection()
*/
@Override
public void destroy() {
resetConnection();
}
/**
* Reset the underlying shared Connection, to be reinitialized on next access.
* @see #closeConnection
*/
public void resetConnection() {
synchronized (this.connectionMonitor) {
if (this.connection != null) {
closeConnection(this.connection);
}
this.connection = null;
}
}
/**
* Create a JMS Connection via this template's ConnectionFactory.
* @return the new JMS Connection
@@ -501,6 +528,19 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
}
}
/**
* Reset the underlying shared Connection, to be reinitialized on next access.
* @see #closeConnection
*/
public void resetConnection() {
synchronized (this.connectionMonitor) {
if (this.connection != null) {
closeConnection(this.connection);
}
this.connection = null;
}
}
/**
* Close the given Connection.
* @param con the Connection to close