| Method from org.springframework.jms.listener.AbstractJmsListeningContainer Detail: |
public void afterPropertiesSet() {
super.afterPropertiesSet();
validateConfiguration();
initialize();
}
|
protected Connection createSharedConnection() throws JMSException {
Connection con = createConnection();
try {
prepareSharedConnection(con);
return con;
}
catch (JMSException ex) {
JmsUtils.closeConnection(con);
throw ex;
}
}
Create a shared Connection for this container.
The default implementation creates a standard Connection
and prepares it through #prepareSharedConnection . |
public void destroy() {
shutdown();
}
Calls #shutdown() when the BeanFactory destroys the container instance. |
abstract protected void doInitialize() throws JMSException
Register any invokers within this container.
Subclasses need to implement this method for their specific
invoker management process.
A shared JMS Connection, if any, will already have been
started at this point. |
protected void doRescheduleTask(Object task) {
throw new UnsupportedOperationException(
ClassUtils.getShortName(getClass()) + " does not support rescheduling of tasks");
}
Reschedule the given task object immediately.
To be implemented by subclasses if they ever call
rescheduleTaskIfNecessary.
This implementation throws an UnsupportedOperationException. |
abstract protected void doShutdown() throws JMSException
Close the registered invokers.
Subclasses need to implement this method for their specific
invoker management process.
A shared JMS Connection, if any, will automatically be closed
afterwards. |
protected void doStart() throws JMSException {
// Lazily establish a shared Connection, if necessary.
if (sharedConnectionEnabled()) {
establishSharedConnection();
}
// Reschedule paused tasks, if any.
synchronized (this.lifecycleMonitor) {
this.running = true;
this.lifecycleMonitor.notifyAll();
resumePausedTasks();
}
// Start the shared Connection, if any.
if (sharedConnectionEnabled()) {
startSharedConnection();
}
}
Start the shared Connection, if any, and notify all invoker tasks. |
protected void doStop() throws JMSException {
synchronized (this.lifecycleMonitor) {
this.running = false;
this.lifecycleMonitor.notifyAll();
}
if (sharedConnectionEnabled()) {
stopSharedConnection();
}
}
Notify all invoker tasks and stop the shared Connection, if any. |
protected void establishSharedConnection() throws JMSException {
synchronized (this.sharedConnectionMonitor) {
if (this.sharedConnection == null) {
this.sharedConnection = createSharedConnection();
logger.debug("Established shared JMS Connection");
}
}
}
Establish a shared Connection for this container.
The default implementation delegates to #createSharedConnection() ,
which does one immediate attempt and throws an exception if it fails.
Can be overridden to have a recovery process in place, retrying
until a Connection can be successfully established. |
protected final String getBeanName() {
return this.beanName;
}
Return the bean name that this listener container has been assigned
in its containing bean factory, if any. |
public String getClientId() {
return this.clientId;
}
Return the JMS client ID for the shared Connection created and used
by this container, if any. |
public int getPausedTaskCount() {
synchronized (this.lifecycleMonitor) {
return this.pausedTasks.size();
}
}
|
protected final Connection getSharedConnection() {
if (!sharedConnectionEnabled()) {
throw new IllegalStateException(
"This listener container does not maintain a shared Connection");
}
synchronized (this.sharedConnectionMonitor) {
if (this.sharedConnection == null) {
throw new SharedConnectionNotInitializedException(
"This listener container's shared Connection has not been initialized yet");
}
return this.sharedConnection;
}
}
Return the shared JMS Connection maintained by this container.
Available after initialization. |
public void initialize() throws JmsException {
try {
synchronized (this.lifecycleMonitor) {
this.active = true;
this.lifecycleMonitor.notifyAll();
}
if (this.autoStartup) {
doStart();
}
doInitialize();
}
catch (JMSException ex) {
synchronized (this.sharedConnectionMonitor) {
ConnectionFactoryUtils.releaseConnection(this.sharedConnection, getConnectionFactory(), this.autoStartup);
}
throw convertJmsAccessException(ex);
}
}
|
public final boolean isActive() {
synchronized (this.lifecycleMonitor) {
return this.active;
}
}
Return whether this container is currently active,
that is, whether it has been set up but not shut down yet. |
public final boolean isRunning() {
synchronized (this.lifecycleMonitor) {
return (this.running && runningAllowed());
}
}
Determine whether this container is currently running,
that is, whether it has been started and not stopped yet. |
protected void logRejectedTask(Object task,
RuntimeException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Listener container task [" + task + "] has been rejected and paused: " + ex);
}
}
|
protected void prepareSharedConnection(Connection connection) throws JMSException {
String clientId = getClientId();
if (clientId != null) {
connection.setClientID(clientId);
}
}
Prepare the given Connection, which is about to be registered
as shared Connection for this container.
The default implementation sets the specified client id, if any.
Subclasses can override this to apply further settings. |
protected final void refreshSharedConnection() throws JMSException {
synchronized (this.sharedConnectionMonitor) {
ConnectionFactoryUtils.releaseConnection(
this.sharedConnection, getConnectionFactory(), this.sharedConnectionStarted);
this.sharedConnection = createSharedConnection();
if (this.sharedConnectionStarted) {
this.sharedConnection.start();
}
}
}
Refresh the shared Connection that this container holds.
Called on startup and also after an infrastructure exception
that occurred during invoker setup and/or execution. |
protected final boolean rescheduleTaskIfNecessary(Object task) {
Assert.notNull(task, "Task object must not be null");
if (this.running) {
try {
doRescheduleTask(task);
}
catch (RuntimeException ex) {
logRejectedTask(task, ex);
this.pausedTasks.add(task);
}
return true;
}
else if (this.active) {
this.pausedTasks.add(task);
return true;
}
else {
return false;
}
}
Take the given task object and reschedule it, either immediately if
this container is currently running, or later once this container
has been restarted.
If this container has already been shut down, the task will not
get rescheduled at all. |
protected void resumePausedTasks() {
synchronized (this.lifecycleMonitor) {
if (!this.pausedTasks.isEmpty()) {
for (Iterator it = this.pausedTasks.iterator(); it.hasNext();) {
Object task = it.next();
try {
doRescheduleTask(task);
it.remove();
if (logger.isDebugEnabled()) {
logger.debug("Resumed paused task: " + task);
}
}
catch (RuntimeException ex) {
logRejectedTask(task, ex);
// Keep the task in paused mode...
}
}
}
}
}
Try to resume all paused tasks.
Tasks for which rescheduling failed simply remain in paused mode. |
protected boolean runningAllowed() {
return true;
}
Check whether this container's listeners are generally allowed to run.
This implementation always returns true; the default 'running'
state is purely determined by #start() / #stop() .
Subclasses may override this method to check against temporary
conditions that prevent listeners from actually running. In other words,
they may apply further restrictions to the 'running' state, returning
false if such a restriction prevents listeners from running. |
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
|
public void setBeanName(String beanName) {
this.beanName = beanName;
}
|
public void setClientId(String clientId) {
this.clientId = clientId;
}
Specify the JMS client id for a shared Connection created and used
by this container.
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. |
abstract protected boolean sharedConnectionEnabled()
Return whether a shared JMS Connection should be maintained
by this container base class. |
public void shutdown() throws JmsException {
logger.debug("Shutting down JMS listener container");
boolean wasRunning = false;
synchronized (this.lifecycleMonitor) {
wasRunning = this.running;
this.running = false;
this.active = false;
this.lifecycleMonitor.notifyAll();
}
// Stop shared Connection early, if necessary.
if (wasRunning && sharedConnectionEnabled()) {
try {
stopSharedConnection();
}
catch (Throwable ex) {
logger.debug("Could not stop JMS Connection on shutdown", ex);
}
}
// Shut down the invokers.
try {
doShutdown();
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
finally {
if (sharedConnectionEnabled()) {
synchronized (this.sharedConnectionMonitor) {
ConnectionFactoryUtils.releaseConnection(this.sharedConnection, getConnectionFactory(), false);
this.sharedConnection = null;
}
}
}
}
Stop the shared Connection, call #doShutdown() ,
and close this container. |
public void start() throws JmsException {
try {
doStart();
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
}
|
protected void startSharedConnection() throws JMSException {
synchronized (this.sharedConnectionMonitor) {
this.sharedConnectionStarted = true;
if (this.sharedConnection != null) {
try {
this.sharedConnection.start();
}
catch (javax.jms.IllegalStateException ex) {
logger.debug("Ignoring Connection start exception - assuming already started: " + ex);
}
}
}
}
Start the shared Connection. |
public void stop() throws JmsException {
try {
doStop();
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
}
|
protected void stopSharedConnection() throws JMSException {
synchronized (this.sharedConnectionMonitor) {
this.sharedConnectionStarted = false;
if (this.sharedConnection != null) {
try {
this.sharedConnection.stop();
}
catch (javax.jms.IllegalStateException ex) {
logger.debug("Ignoring Connection stop exception - assuming already stopped: " + ex);
}
}
}
}
Stop the shared Connection. |
protected void validateConfiguration() {
}
|
protected final void waitWhileNotRunning() {
synchronized (this.lifecycleMonitor) {
boolean interrupted = false;
while (this.active && !isRunning()) {
if (interrupted) {
throw new IllegalStateException("Thread was interrupted while waiting for " +
"a restart of the listener container, but container is still stopped");
}
try {
this.lifecycleMonitor.wait();
}
catch (InterruptedException ex) {
// Re-interrupt current thread, to allow other threads to react.
Thread.currentThread().interrupt();
interrupted = true;
}
}
}
}
|