org.springframework.jms.connection

## Class SingleConnectionFactory

- java.lang.Object
- - org.springframework.jms.connection.SingleConnectionFactory

- All Implemented Interfaces:
    ConnectionFactory, ExceptionListener, QueueConnectionFactory, TopicConnectionFactory, DisposableBean, InitializingBean
  Direct Known Subclasses:
    CachingConnectionFactory

      public class SingleConnectionFactory
      extends Object
      implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, ExceptionListener, InitializingBean, DisposableBean

  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 e.g. 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:
    `JmsTemplate`, `SimpleMessageListenerContainer`, `DefaultMessageListenerContainer.setCacheLevel(int)`

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected Log` | `logger`

  - ### Constructor Summary

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

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `afterPropertiesSet()` Make sure a Connection or ConnectionFactory has been set.
    `protected void` | `closeConnection(Connection con)` Close the given Connection.
    `Connection` | `createConnection()`
    `Connection` | `createConnection(String username, String password)`
    `JMSContext` | `createContext()`
    `JMSContext` | `createContext(int sessionMode)`
    `JMSContext` | `createContext(String userName, String password)`
    `JMSContext` | `createContext(String userName, String password, int sessionMode)`
    `QueueConnection` | `createQueueConnection()`
    `QueueConnection` | `createQueueConnection(String username, String password)`
    `protected Session` | `createSession(Connection con, Integer mode)` Create a default Session for this ConnectionFactory, adapting to JMS 1.0.2 style queue/topic mode if necessary.
    `TopicConnection` | `createTopicConnection()`
    `TopicConnection` | `createTopicConnection(String username, String password)`
    `void` | `destroy()` Close the underlying shared connection.
    `protected Connection` | `doCreateConnection()` Create a JMS Connection via this template's ConnectionFactory.
    `protected String` | `getClientId()` Return a JMS client ID for the single Connection created and exposed by this ConnectionFactory, if any.
    `protected Connection` | `getConnection()` Obtain an initialized shared Connection.
    `protected ExceptionListener` | `getExceptionListener()` Return the JMS ExceptionListener implementation that should be registered with the single Connection created by this factory, if any.
    `protected Session` | `getSession(Connection con, Integer mode)` Template method for obtaining a (potentially cached) Session.
    `protected Connection` | `getSharedConnectionProxy(Connection target)` Wrap the given Connection with a proxy that delegates every method call to it but suppresses close calls.
    `ConnectionFactory` | `getTargetConnectionFactory()` Return the target ConnectionFactory which will be used to lazily create a single Connection, if any.
    `void` | `initConnection()` Initialize the underlying shared Connection.
    `protected boolean` | `isReconnectOnException()` Return whether the single Connection should be renewed when a JMSException is reported by the underlying Connection.
    `void` | `onException(JMSException ex)` Exception listener callback that renews the underlying single Connection.
    `protected void` | `prepareConnection(Connection con)` Prepare the given Connection before it is exposed.
    `void` | `resetConnection()` Reset the underlying shared Connection, to be reinitialized on next access.
    `void` | `setClientId(String clientId)` Specify a JMS client ID for the single Connection created and exposed by this ConnectionFactory.
    `void` | `setExceptionListener(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(ConnectionFactory targetConnectionFactory)` Set the target ConnectionFactory which will be used to lazily create a single Connection.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### logger

          protected final Log logger

  - ### Constructor Detail

    - #### SingleConnectionFactory

          public SingleConnectionFactory()

      Create a new SingleConnectionFactory for bean-style usage.
      See Also:
        `setTargetConnectionFactory(javax.jms.ConnectionFactory)`

    - #### SingleConnectionFactory

          public SingleConnectionFactory(Connection targetConnection)

      Create a new SingleConnectionFactory that always returns the given Connection.
      Parameters:
        `targetConnection` - the single Connection

    - #### SingleConnectionFactory

          public SingleConnectionFactory(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 Detail

    - #### setTargetConnectionFactory

          public void setTargetConnectionFactory(@Nullable
                                                 ConnectionFactory targetConnectionFactory)

      Set the target ConnectionFactory which will be used to lazily create a single Connection.

    - #### getTargetConnectionFactory

          @Nullable
          public 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:
        `Connection.setClientID(java.lang.String)`, `setTargetConnectionFactory(javax.jms.ConnectionFactory)`

    - #### getClientId

          @Nullable
          protected String getClientId()

      Return a JMS client ID for the single Connection created and exposed by this ConnectionFactory, if any.

    - #### setExceptionListener

          public void setExceptionListener(@Nullable
                                           ExceptionListener exceptionListener)

      Specify an JMS ExceptionListener implementation that should be registered with the single Connection created by this factory.
      See Also:
        `setReconnectOnException(boolean)`

    - #### getExceptionListener

          @Nullable
          protected 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:
        `setExceptionListener(javax.jms.ExceptionListener)`

    - #### 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 Connection createConnection()
                                      throws JMSException

      Specified by:
        `createConnection` in interface `ConnectionFactory`
      Throws:
        `JMSException`

    - #### createConnection

          public Connection createConnection(String username,
                                             String password)
                                      throws JMSException

      Specified by:
        `createConnection` in interface `ConnectionFactory`
      Throws:
        `JMSException`

    - #### createQueueConnection

          public QueueConnection createQueueConnection()
                                                throws JMSException

      Specified by:
        `createQueueConnection` in interface `QueueConnectionFactory`
      Throws:
        `JMSException`

    - #### createQueueConnection

          public QueueConnection createQueueConnection(String username,
                                                       String password)
                                                throws JMSException

      Specified by:
        `createQueueConnection` in interface `QueueConnectionFactory`
      Throws:
        `JMSException`

    - #### createTopicConnection

          public TopicConnection createTopicConnection()
                                                throws JMSException

      Specified by:
        `createTopicConnection` in interface `TopicConnectionFactory`
      Throws:
        `JMSException`

    - #### createTopicConnection

          public TopicConnection createTopicConnection(String username,
                                                       String password)
                                                throws JMSException

      Specified by:
        `createTopicConnection` in interface `TopicConnectionFactory`
      Throws:
        `JMSException`

    - #### createContext

          public JMSContext createContext()

      Specified by:
        `createContext` in interface `ConnectionFactory`

    - #### createContext

          public JMSContext createContext(String userName,
                                          String password)

      Specified by:
        `createContext` in interface `ConnectionFactory`

    - #### createContext

          public JMSContext createContext(String userName,
                                          String password,
                                          int sessionMode)

      Specified by:
        `createContext` in interface `ConnectionFactory`

    - #### createContext

          public JMSContext createContext(int sessionMode)

      Specified by:
        `createContext` in interface `ConnectionFactory`

    - #### getConnection

          protected Connection getConnection()
                                      throws JMSException

      Obtain an initialized shared Connection.
      Returns:
        the Connection (never `null`)
      Throws:
        `JMSException` - if thrown by JMS API methods
      See Also:
        `initConnection()`

    - #### initConnection

          public void initConnection()
                              throws JMSException

      Initialize the underlying shared Connection.

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

      Throws:
        `JMSException` - if thrown by JMS API methods
      See Also:
        `prepareConnection(javax.jms.Connection)`

    - #### onException

          public void onException(JMSException ex)

      Exception listener callback that renews the underlying single Connection.
      Specified by:
        `onException` in interface `ExceptionListener`
      See Also:
        `resetConnection()`

    - #### 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:
        `resetConnection()`

    - #### resetConnection

          public void resetConnection()

      Reset the underlying shared Connection, to be reinitialized on next access.
      See Also:
        `closeConnection(javax.jms.Connection)`

    - #### doCreateConnection

          protected Connection doCreateConnection()
                                           throws JMSException

      Create a JMS Connection via this template's ConnectionFactory.
      Returns:
        the new JMS Connection
      Throws:
        `JMSException` - if thrown by JMS API methods

    - #### prepareConnection

          protected void prepareConnection(Connection con)
                                    throws 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:
        `JMSException` - if thrown by JMS API methods
      See Also:
        `setExceptionListener(javax.jms.ExceptionListener)`, `setReconnectOnException(boolean)`

    - #### getSession

          @Nullable
          protected Session getSession(Connection con,
                                                 Integer mode)
                                          throws 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(javax.jms.Connection, java.lang.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:
        `JMSException` - if thrown by the JMS API

    - #### createSession

          protected Session createSession(Connection con,
                                          Integer mode)
                                   throws 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:
        `JMSException` - if thrown by the JMS API

    - #### closeConnection

          protected void closeConnection(Connection con)

      Close the given Connection.
      Parameters:
        `con` - the Connection to close

    - #### getSharedConnectionProxy

          protected Connection getSharedConnectionProxy(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