public class SingleConnectionFactory extends java.lang.Object implements InitializingBean, DisposableBean
createConnection()
calls, and ignores calls to
javax.jms.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.
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.
JmsTemplate
,
SimpleMessageListenerContainer
,
DefaultMessageListenerContainer.setCacheLevel(int)
Modifier and Type | Class and Description |
---|---|
private class |
SingleConnectionFactory.AggregatedExceptionListener
Internal aggregated ExceptionListener for handling the internal
recovery listener in combination with user-specified listeners.
|
private class |
SingleConnectionFactory.SharedConnectionInvocationHandler
Invocation handler for a cached JMS Connection proxy.
|
Modifier and Type | Field and Description |
---|---|
private SingleConnectionFactory.AggregatedExceptionListener |
aggregatedExceptionListener
An internal aggregator allowing for per-connection ExceptionListeners
|
private java.lang.String |
clientId |
private Connection |
connection
The target Connection
|
private java.lang.Object |
connectionMonitor
Synchronization monitor for the shared Connection
|
private ExceptionListener |
exceptionListener |
protected Log |
logger |
private java.lang.Boolean |
pubSubMode
A hint whether to create a queue or topic connection
|
private boolean |
reconnectOnException |
private int |
startedCount
Whether the shared Connection has been started
|
private ConnectionFactory |
targetConnectionFactory |
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.
|
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(java.lang.String username,
java.lang.String password) |
JMSContext |
createContext() |
JMSContext |
createContext(int sessionMode) |
JMSContext |
createContext(java.lang.String userName,
java.lang.String password) |
JMSContext |
createContext(java.lang.String userName,
java.lang.String password,
int sessionMode) |
QueueConnection |
createQueueConnection() |
QueueConnection |
createQueueConnection(java.lang.String username,
java.lang.String password) |
protected Session |
createSession(Connection con,
java.lang.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(java.lang.String username,
java.lang.String password) |
void |
destroy()
Close the underlying shared connection.
|
protected Connection |
doCreateConnection()
Create a JMS Connection via this template's ConnectionFactory.
|
protected java.lang.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,
java.lang.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.
|
private ConnectionFactory |
obtainTargetConnectionFactory() |
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(java.lang.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.
|
protected final Log logger
private ConnectionFactory targetConnectionFactory
private java.lang.String clientId
private ExceptionListener exceptionListener
private boolean reconnectOnException
private Connection connection
private java.lang.Boolean pubSubMode
private SingleConnectionFactory.AggregatedExceptionListener aggregatedExceptionListener
private int startedCount
private final java.lang.Object connectionMonitor
public SingleConnectionFactory()
public SingleConnectionFactory(Connection targetConnection)
targetConnection
- the single Connectionpublic SingleConnectionFactory(ConnectionFactory targetConnectionFactory)
targetConnectionFactory
- the target ConnectionFactorypublic void setTargetConnectionFactory(ConnectionFactory targetConnectionFactory)
public ConnectionFactory getTargetConnectionFactory()
public void setClientId(java.lang.String clientId)
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.
javax.jms.Connection#setClientID
,
setTargetConnectionFactory(ConnectionFactory)
protected java.lang.String getClientId()
public void setExceptionListener(ExceptionListener exceptionListener)
setReconnectOnException(boolean)
protected ExceptionListener getExceptionListener()
public void setReconnectOnException(boolean reconnectOnException)
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.
setExceptionListener(ExceptionListener)
protected boolean isReconnectOnException()
public void afterPropertiesSet()
afterPropertiesSet
in interface InitializingBean
public Connection createConnection() throws JMSException
JMSException
public Connection createConnection(java.lang.String username, java.lang.String password) throws JMSException
JMSException
public QueueConnection createQueueConnection() throws JMSException
JMSException
public QueueConnection createQueueConnection(java.lang.String username, java.lang.String password) throws JMSException
JMSException
public TopicConnection createTopicConnection() throws JMSException
JMSException
public TopicConnection createTopicConnection(java.lang.String username, java.lang.String password) throws JMSException
JMSException
public JMSContext createContext()
public JMSContext createContext(java.lang.String userName, java.lang.String password)
public JMSContext createContext(java.lang.String userName, java.lang.String password, int sessionMode)
public JMSContext createContext(int sessionMode)
private ConnectionFactory obtainTargetConnectionFactory()
protected Connection getConnection() throws JMSException
null
)javax.jms.JMSException
- if thrown by JMS API methodsJMSException
initConnection()
public void initConnection() throws JMSException
Closes and reinitializes the Connection if an underlying Connection is present already.
javax.jms.JMSException
- if thrown by JMS API methodsJMSException
prepareConnection(Connection)
public void onException(JMSException ex)
resetConnection()
public void destroy()
As this bean implements DisposableBean, a bean factory will automatically invoke this on destruction of its cached singletons.
destroy
in interface DisposableBean
resetConnection()
public void resetConnection()
closeConnection(Connection)
protected Connection doCreateConnection() throws JMSException
javax.jms.JMSException
- if thrown by JMS API methodsJMSException
protected void prepareConnection(Connection con) throws JMSException
The default implementation applies ExceptionListener and client id. Can be overridden in subclasses.
con
- the Connection to prepareJMSException
- if thrown by JMS API methodssetExceptionListener(ExceptionListener)
,
setReconnectOnException(boolean)
protected Session getSession(Connection con, java.lang.Integer mode) throws JMSException
The default implementation always returns null
.
Subclasses may override this for exposing specific Session handles,
possibly delegating to createSession(Connection, java.lang.Integer)
for the creation of raw
Session objects that will then get wrapped and returned from here.
con
- the JMS Connection to operate onmode
- the Session acknowledgement mode
(Session.TRANSACTED
or one of the common modes)null
to indicate
creation of a raw standard SessionJMSException
- if thrown by the JMS APIprotected Session createSession(Connection con, java.lang.Integer mode) throws JMSException
con
- the JMS Connection to operate onmode
- the Session acknowledgement mode
(Session.TRANSACTED
or one of the common modes)JMSException
- if thrown by the JMS APIprotected void closeConnection(Connection con)
con
- the Connection to closeprotected Connection getSharedConnectionProxy(Connection target)
target
- the original Connection to wrap