|
Spring Framework example source code file (AbstractJmsListeningContainer.java)
The Spring Framework AbstractJmsListeningContainer.java source code/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.jms.listener;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.jms.Connection;
import javax.jms.JMSException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.Lifecycle;
import org.springframework.jms.JmsException;
import org.springframework.jms.connection.ConnectionFactoryUtils;
import org.springframework.jms.support.JmsUtils;
import org.springframework.jms.support.destination.JmsDestinationAccessor;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Common base class for all containers which need to implement listening
* based on a JMS Connection (either shared or freshly obtained for each attempt).
* Inherits basic Connection and Session configuration handling from the
* {@link org.springframework.jms.support.JmsAccessor} base class.
*
* <p>This class provides basic lifecycle management, in particular management
* of a shared JMS Connection. Subclasses are supposed to plug into this
* lifecycle, implementing the {@link #sharedConnectionEnabled()} as well
* as the {@link #doInitialize()} and {@link #doShutdown()} template methods.
*
* <p>This base class does not assume any specific listener programming model
* or listener invoker mechanism. It just provides the general runtime
* lifecycle management needed for any kind of JMS-based listening mechanism
* that operates on a JMS Connection/Session.
*
* <p>For a concrete listener programming model, check out the
* {@link AbstractMessageListenerContainer} subclass. For a concrete listener
* invoker mechanism, check out the {@link DefaultMessageListenerContainer} class.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see #sharedConnectionEnabled()
* @see #doInitialize()
* @see #doShutdown()
*/
public abstract class AbstractJmsListeningContainer extends JmsDestinationAccessor
implements Lifecycle, BeanNameAware, DisposableBean {
private String clientId;
private boolean autoStartup = true;
private String beanName;
private Connection sharedConnection;
private boolean sharedConnectionStarted = false;
protected final Object sharedConnectionMonitor = new Object();
private boolean active = false;
private boolean running = false;
private final List pausedTasks = new LinkedList();
protected final Object lifecycleMonitor = new Object();
/**
* Specify the JMS client id for a shared Connection created and used
* by this container.
* <p>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 javax.jms.Connection#setClientID
* @see #setConnectionFactory
*/
public void setClientId(String clientId) {
this.clientId = clientId;
}
/**
* Return the JMS client ID for the shared Connection created and used
* by this container, if any.
*/
public String getClientId() {
return this.clientId;
}
/**
* Set whether to automatically start the container after initialization.
* <p>Default is "true"; set this to "false" to allow for manual startup
* through the {@link #start()} method.
*/
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
/**
* Return the bean name that this listener container has been assigned
* in its containing bean factory, if any.
*/
protected final String getBeanName() {
return this.beanName;
}
/**
* Delegates to {@link #validateConfiguration()} and {@link #initialize()}.
*/
public void afterPropertiesSet() {
super.afterPropertiesSet();
validateConfiguration();
initialize();
}
/**
* Validate the configuration of this container.
* <p>The default implementation is empty. To be overridden in subclasses.
*/
protected void validateConfiguration() {
}
/**
* Calls {@link #shutdown()} when the BeanFactory destroys the container instance.
* @see #shutdown()
*/
public void destroy() {
shutdown();
}
//-------------------------------------------------------------------------
// Lifecycle methods for starting and stopping the container
//-------------------------------------------------------------------------
/**
* Initialize this container.
* <p>Creates a JMS Connection, starts the {@link javax.jms.Connection}
* (if {@link #setAutoStartup(boolean) "autoStartup"} hasn't been turned off),
* and calls {@link #doInitialize()}.
* @throws org.springframework.jms.JmsException if startup failed
*/
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);
}
}
/**
* Stop the shared Connection, call {@link #doShutdown()},
* and close this container.
* @throws JmsException if shutdown failed
*/
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);
}
}
}
}
/**
* Return whether this container is currently active,
* that is, whether it has been set up but not shut down yet.
*/
public final boolean isActive() {
synchronized (this.lifecycleMonitor) {
return this.active;
}
}
/**
* Start this container.
* @throws JmsException if starting failed
* @see #doStart
*/
public void start() throws JmsException {
try {
doStart();
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
}
/**
* Start the shared Connection, if any, and notify all invoker tasks.
* @throws JMSException if thrown by JMS API methods
* @see #startSharedConnection
*/
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();
}
}
/**
* Stop this container.
* @throws JmsException if stopping failed
* @see #doStop
*/
public void stop() throws JmsException {
try {
doStop();
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
}
/**
* Notify all invoker tasks and stop the shared Connection, if any.
* @throws JMSException if thrown by JMS API methods
* @see #stopSharedConnection
*/
protected void doStop() throws JMSException {
synchronized (this.lifecycleMonitor) {
this.running = false;
this.lifecycleMonitor.notifyAll();
}
if (sharedConnectionEnabled()) {
stopSharedConnection();
}
}
/**
* Determine whether this container is currently running,
* that is, whether it has been started and not stopped yet.
* @see #start()
* @see #stop()
* @see #runningAllowed()
*/
public final boolean isRunning() {
synchronized (this.lifecycleMonitor) {
return (this.running && runningAllowed());
}
}
/**
* Check whether this container's listeners are generally allowed to run.
* <p>This implementation always returns
Other Spring Framework examples (source code examples)Here is a short list of links related to this Spring Framework AbstractJmsListeningContainer.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.