Class SingleConnectionFactory

java.lang.Object
org.springframework.jms.connection.SingleConnectionFactory
All Implemented Interfaces:
jakarta.jms.ConnectionFactory, jakarta.jms.ExceptionListener, jakarta.jms.QueueConnectionFactory, jakarta.jms.TopicConnectionFactory, DisposableBean, InitializingBean, Lifecycle
Direct Known Subclasses:
CachingConnectionFactory

public class SingleConnectionFactory extends Object implements jakarta.jms.ConnectionFactory, jakarta.jms.QueueConnectionFactory, jakarta.jms.TopicConnectionFactory, jakarta.jms.ExceptionListener, InitializingBean, DisposableBean, Lifecycle
A JMS ConnectionFactory adapter that returns the same Connection from all createConnection() calls, and ignores calls to Connection.close(). According to the JMS Connection model, this is perfectly thread-safe (in contrast to, for example, JDBC). The shared Connection can be automatically recovered in case of an Exception.

You can either pass in a specific JMS Connection directly or let this factory lazily create a Connection via a given target ConnectionFactory. This factory generally works with JMS 1.1 as well as the JMS 1.0.2 API.

Note that when using the JMS 1.0.2 API, this ConnectionFactory will switch into queue/topic mode according to the JMS API methods used at runtime: createQueueConnection and createTopicConnection will lead to queue/topic mode, respectively; generic createConnection calls will lead to a JMS 1.1 connection which is able to serve both modes.

As of Spring Framework 5, this class supports JMS 2.0 JMSContext calls and therefore requires the JMS 2.0 API to be present at runtime. It may nevertheless run against a JMS 1.1 driver (bound to the JMS 2.0 API) as long as no actual JMS 2.0 calls are triggered by the application's setup.

Useful for testing and standalone environments in order to keep using the same Connection for multiple JmsTemplate calls, without having a pooling ConnectionFactory underneath. This may span any number of transactions, even concurrently executing transactions.

Note that Spring's message listener containers support the use of a shared Connection within each listener container instance. Using SingleConnectionFactory in combination only really makes sense for sharing a single JMS Connection across multiple listener containers.

Since:
1.1
Author:
Juergen Hoeller, Mark Pollack
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected final org.apache.commons.logging.Log
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    Create a new SingleConnectionFactory for bean-style usage.
    SingleConnectionFactory(jakarta.jms.Connection targetConnection)
    Create a new SingleConnectionFactory that always returns the given Connection.
    SingleConnectionFactory(jakarta.jms.ConnectionFactory targetConnectionFactory)
    Create a new SingleConnectionFactory that always returns a single Connection that it will lazily create via the given target ConnectionFactory.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Make sure a Connection or ConnectionFactory has been set.
    protected void
    closeConnection(jakarta.jms.Connection con)
    Close the given Connection.
    jakarta.jms.Connection
     
    jakarta.jms.Connection
    createConnection(String username, String password)
     
    jakarta.jms.JMSContext
     
    jakarta.jms.JMSContext
    createContext(int sessionMode)
     
    jakarta.jms.JMSContext
    createContext(String userName, String password)
     
    jakarta.jms.JMSContext
    createContext(String userName, String password, int sessionMode)
     
    jakarta.jms.QueueConnection
     
    jakarta.jms.QueueConnection
    createQueueConnection(String username, String password)
     
    protected jakarta.jms.Session
    createSession(jakarta.jms.Connection con, Integer mode)
    Create a default Session for this ConnectionFactory, adapting to JMS 1.0.2 style queue/topic mode if necessary.
    jakarta.jms.TopicConnection
     
    jakarta.jms.TopicConnection
    createTopicConnection(String username, String password)
     
    void
    Close the underlying shared connection.
    protected jakarta.jms.Connection
    Create a JMS Connection via this template's ConnectionFactory.
    protected @Nullable String
    Return a JMS client ID for the single Connection created and exposed by this ConnectionFactory, if any.
    protected jakarta.jms.Connection
    Obtain an initialized shared Connection.
    protected @Nullable jakarta.jms.ExceptionListener
    Return the JMS ExceptionListener implementation that should be registered with the single Connection created by this factory, if any.
    protected @Nullable jakarta.jms.Session
    getSession(jakarta.jms.Connection con, Integer mode)
    Template method for obtaining a (potentially cached) Session.
    protected jakarta.jms.Connection
    getSharedConnectionProxy(jakarta.jms.Connection target)
    Wrap the given Connection with a proxy that delegates every method call to it but suppresses close calls.
    @Nullable jakarta.jms.ConnectionFactory
    Return the target ConnectionFactory which will be used to lazily create a single Connection, if any.
    void
    Initialize the underlying shared Connection.
    protected boolean
    Return whether the single Connection should be renewed when a JMSException is reported by the underlying Connection.
    boolean
    Check whether there is currently an underlying connection.
    void
    onException(jakarta.jms.JMSException ex)
    Exception listener callback that renews the underlying single Connection.
    protected void
    prepareConnection(jakarta.jms.Connection con)
    Prepare the given Connection before it is exposed.
    void
    Reset the underlying shared Connection, to be reinitialized on next access.
    void
    Specify a JMS client ID for the single Connection created and exposed by this ConnectionFactory.
    void
    setExceptionListener(@Nullable jakarta.jms.ExceptionListener exceptionListener)
    Specify an JMS ExceptionListener implementation that should be registered with the single Connection created by this factory.
    void
    setReconnectOnException(boolean reconnectOnException)
    Specify whether the single Connection should be reset (to be subsequently renewed) when a JMSException is reported by the underlying Connection.
    void
    setTargetConnectionFactory(@Nullable jakarta.jms.ConnectionFactory targetConnectionFactory)
    Set the target ConnectionFactory which will be used to lazily create a single Connection.
    void
    Initialize the underlying shared connection on start.
    void
    Reset the underlying shared connection on stop.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • logger

      protected final org.apache.commons.logging.Log logger
  • Constructor Details

    • SingleConnectionFactory

      public SingleConnectionFactory()
      Create a new SingleConnectionFactory for bean-style usage.
      See Also:
    • SingleConnectionFactory

      public SingleConnectionFactory(jakarta.jms.Connection targetConnection)
      Create a new SingleConnectionFactory that always returns the given Connection.
      Parameters:
      targetConnection - the single Connection
    • SingleConnectionFactory

      public SingleConnectionFactory(jakarta.jms.ConnectionFactory targetConnectionFactory)
      Create a new SingleConnectionFactory that always returns a single Connection that it will lazily create via the given target ConnectionFactory.
      Parameters:
      targetConnectionFactory - the target ConnectionFactory
  • Method Details

    • setTargetConnectionFactory

      public void setTargetConnectionFactory(@Nullable jakarta.jms.ConnectionFactory targetConnectionFactory)
      Set the target ConnectionFactory which will be used to lazily create a single Connection.
    • getTargetConnectionFactory

      public @Nullable jakarta.jms.ConnectionFactory getTargetConnectionFactory()
      Return the target ConnectionFactory which will be used to lazily create a single Connection, if any.
    • setClientId

      public void setClientId(@Nullable String clientId)
      Specify a JMS client ID for the single Connection created and exposed by this ConnectionFactory.

      Note that client IDs need to be unique among all active Connections of the underlying JMS provider. Furthermore, a client ID can only be assigned if the original ConnectionFactory hasn't already assigned one.

      See Also:
    • getClientId

      protected @Nullable String getClientId()
      Return a JMS client ID for the single Connection created and exposed by this ConnectionFactory, if any.
    • setExceptionListener

      public void setExceptionListener(@Nullable jakarta.jms.ExceptionListener exceptionListener)
      Specify an JMS ExceptionListener implementation that should be registered with the single Connection created by this factory.
      See Also:
    • getExceptionListener

      protected @Nullable jakarta.jms.ExceptionListener getExceptionListener()
      Return the JMS ExceptionListener implementation that should be registered with the single Connection created by this factory, if any.
    • setReconnectOnException

      public void setReconnectOnException(boolean reconnectOnException)
      Specify whether the single Connection should be reset (to be subsequently renewed) when a JMSException is reported by the underlying Connection.

      Default is "false". Switch this to "true" to automatically trigger recovery based on your JMS provider's exception notifications.

      Internally, this will lead to a special JMS ExceptionListener (this SingleConnectionFactory itself) being registered with the underlying Connection. This can also be combined with a user-specified ExceptionListener, if desired.

      See Also:
    • isReconnectOnException

      protected boolean isReconnectOnException()
      Return whether the single Connection should be renewed when a JMSException is reported by the underlying Connection.
    • afterPropertiesSet

      public void afterPropertiesSet()
      Make sure a Connection or ConnectionFactory has been set.
      Specified by:
      afterPropertiesSet in interface InitializingBean
    • createConnection

      public jakarta.jms.Connection createConnection() throws jakarta.jms.JMSException
      Specified by:
      createConnection in interface jakarta.jms.ConnectionFactory
      Throws:
      jakarta.jms.JMSException
    • createConnection

      public jakarta.jms.Connection createConnection(String username, String password) throws jakarta.jms.JMSException
      Specified by:
      createConnection in interface jakarta.jms.ConnectionFactory
      Throws:
      jakarta.jms.JMSException
    • createQueueConnection

      public jakarta.jms.QueueConnection createQueueConnection() throws jakarta.jms.JMSException
      Specified by:
      createQueueConnection in interface jakarta.jms.QueueConnectionFactory
      Throws:
      jakarta.jms.JMSException
    • createQueueConnection

      public jakarta.jms.QueueConnection createQueueConnection(String username, String password) throws jakarta.jms.JMSException
      Specified by:
      createQueueConnection in interface jakarta.jms.QueueConnectionFactory
      Throws:
      jakarta.jms.JMSException
    • createTopicConnection

      public jakarta.jms.TopicConnection createTopicConnection() throws jakarta.jms.JMSException
      Specified by:
      createTopicConnection in interface jakarta.jms.TopicConnectionFactory
      Throws:
      jakarta.jms.JMSException
    • createTopicConnection

      public jakarta.jms.TopicConnection createTopicConnection(String username, String password) throws jakarta.jms.JMSException
      Specified by:
      createTopicConnection in interface jakarta.jms.TopicConnectionFactory
      Throws:
      jakarta.jms.JMSException
    • createContext

      public jakarta.jms.JMSContext createContext()
      Specified by:
      createContext in interface jakarta.jms.ConnectionFactory
    • createContext

      public jakarta.jms.JMSContext createContext(String userName, String password)
      Specified by:
      createContext in interface jakarta.jms.ConnectionFactory
    • createContext

      public jakarta.jms.JMSContext createContext(String userName, String password, int sessionMode)
      Specified by:
      createContext in interface jakarta.jms.ConnectionFactory
    • createContext

      public jakarta.jms.JMSContext createContext(int sessionMode)
      Specified by:
      createContext in interface jakarta.jms.ConnectionFactory
    • getConnection

      protected jakarta.jms.Connection getConnection() throws jakarta.jms.JMSException
      Obtain an initialized shared Connection.
      Returns:
      the Connection (never null)
      Throws:
      jakarta.jms.JMSException - if thrown by JMS API methods
      See Also:
    • onException

      public void onException(jakarta.jms.JMSException ex)
      Exception listener callback that renews the underlying single Connection.
      Specified by:
      onException in interface jakarta.jms.ExceptionListener
      See Also:
    • destroy

      public void destroy()
      Close the underlying shared connection. The provider of this ConnectionFactory needs to care for proper shutdown.

      As this bean implements DisposableBean, a bean factory will automatically invoke this on destruction of its cached singletons.

      Specified by:
      destroy in interface DisposableBean
      See Also:
    • start

      public void start()
      Initialize the underlying shared connection on start.
      Specified by:
      start in interface Lifecycle
      Since:
      6.1
      See Also:
    • stop

      public void stop()
      Reset the underlying shared connection on stop.
      Specified by:
      stop in interface Lifecycle
      Since:
      6.1
      See Also:
    • isRunning

      public boolean isRunning()
      Check whether there is currently an underlying connection.
      Specified by:
      isRunning in interface Lifecycle
      Returns:
      whether the component is currently running
      Since:
      6.1
      See Also:
    • initConnection

      public void initConnection() throws jakarta.jms.JMSException
      Initialize the underlying shared Connection.

      Closes and reinitializes the Connection if an underlying Connection is present already.

      Throws:
      jakarta.jms.JMSException - if thrown by JMS API methods
      See Also:
    • doCreateConnection

      protected jakarta.jms.Connection doCreateConnection() throws jakarta.jms.JMSException
      Create a JMS Connection via this template's ConnectionFactory.
      Returns:
      the new JMS Connection
      Throws:
      jakarta.jms.JMSException - if thrown by JMS API methods
    • prepareConnection

      protected void prepareConnection(jakarta.jms.Connection con) throws jakarta.jms.JMSException
      Prepare the given Connection before it is exposed.

      The default implementation applies ExceptionListener and client id. Can be overridden in subclasses.

      Parameters:
      con - the Connection to prepare
      Throws:
      jakarta.jms.JMSException - if thrown by JMS API methods
      See Also:
    • getSession

      protected @Nullable jakarta.jms.Session getSession(jakarta.jms.Connection con, Integer mode) throws jakarta.jms.JMSException
      Template method for obtaining a (potentially cached) Session.

      The default implementation always returns null. Subclasses may override this for exposing specific Session handles, possibly delegating to createSession(Connection, Integer) for the creation of raw Session objects that will then get wrapped and returned from here.

      Parameters:
      con - the JMS Connection to operate on
      mode - the Session acknowledgement mode (Session.TRANSACTED or one of the common modes)
      Returns:
      the Session to use, or null to indicate creation of a raw standard Session
      Throws:
      jakarta.jms.JMSException - if thrown by the JMS API
    • createSession

      protected jakarta.jms.Session createSession(jakarta.jms.Connection con, Integer mode) throws jakarta.jms.JMSException
      Create a default Session for this ConnectionFactory, adapting to JMS 1.0.2 style queue/topic mode if necessary.
      Parameters:
      con - the JMS Connection to operate on
      mode - the Session acknowledgement mode (Session.TRANSACTED or one of the common modes)
      Returns:
      the newly created Session
      Throws:
      jakarta.jms.JMSException - if thrown by the JMS API
    • resetConnection

      public void resetConnection()
      Reset the underlying shared Connection, to be reinitialized on next access.
      See Also:
    • closeConnection

      protected void closeConnection(jakarta.jms.Connection con)
      Close the given Connection.
      Parameters:
      con - the Connection to close
    • getSharedConnectionProxy

      protected jakarta.jms.Connection getSharedConnectionProxy(jakarta.jms.Connection target)
      Wrap the given Connection with a proxy that delegates every method call to it but suppresses close calls. This is useful for allowing application code to handle a special framework Connection just like an ordinary Connection from a JMS ConnectionFactory.
      Parameters:
      target - the original Connection to wrap
      Returns:
      the wrapped Connection