INT-847 Upgrading to Spring 3.0 snapshot (CI-475 from 2009/11/25).

This commit is contained in:
Mark Fisher
2009-11-26 05:35:38 +00:00
parent 335f394653
commit ffc6dd556d
39 changed files with 295 additions and 251 deletions

View File

@@ -22,9 +22,7 @@ import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.Lifecycle;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.SmartLifecycle;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.context.IntegrationContextUtils;
@@ -32,7 +30,6 @@ import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.endpoint.PollingConsumer;
import org.springframework.integration.endpoint.AbstractEndpoint.StartupMode;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.scheduling.PollerMetadata;
import org.springframework.util.Assert;
@@ -40,8 +37,8 @@ import org.springframework.util.Assert;
/**
* @author Mark Fisher
*/
public class ConsumerEndpointFactoryBean implements FactoryBean, BeanFactoryAware, BeanNameAware,
InitializingBean, Lifecycle, ApplicationListener<ContextRefreshedEvent> {
public class ConsumerEndpointFactoryBean
implements FactoryBean, BeanFactoryAware, BeanNameAware, InitializingBean, SmartLifecycle {
private volatile MessageHandler handler;
@@ -155,20 +152,26 @@ public class ConsumerEndpointFactoryBean implements FactoryBean, BeanFactoryAwar
}
this.endpoint.setBeanName(this.beanName);
this.endpoint.setBeanFactory(this.beanFactory);
if (!this.autoStartup) {
this.endpoint.setStartupMode(StartupMode.MANUAL);
}
this.endpoint.setAutoStartup(this.autoStartup);
this.endpoint.afterPropertiesSet();
this.initialized = true;
}
}
/*
* Lifecycle implementation
* SmartLifecycle implementation (delegates to the created endpoint)
*/
public boolean isAutoStartup() {
return (this.endpoint != null) ? this.endpoint.isAutoStartup() : true;
}
public int getPhase() {
return (this.endpoint != null) ? this.endpoint.getPhase() : 0;
}
public boolean isRunning() {
return (this.endpoint != null ? this.endpoint.isRunning() : false);
return (this.endpoint != null) ? this.endpoint.isRunning() : false;
}
public void start() {
@@ -183,12 +186,10 @@ public class ConsumerEndpointFactoryBean implements FactoryBean, BeanFactoryAwar
}
}
/*
* ApplicationListener implementation
*/
public void onApplicationEvent(ContextRefreshedEvent event) {
this.endpoint.onApplicationEvent(event);
public void stop(Runnable callback) {
if (this.endpoint != null) {
this.endpoint.stop(callback);
}
}
}

View File

@@ -23,13 +23,10 @@ import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.Lifecycle;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.SmartLifecycle;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.endpoint.AbstractEndpoint.StartupMode;
import org.springframework.integration.message.MessageSource;
import org.springframework.integration.scheduling.PollerMetadata;
import org.springframework.util.Assert;
@@ -40,7 +37,7 @@ import org.springframework.util.Assert;
* @author Mark Fisher
*/
public class SourcePollingChannelAdapterFactoryBean implements FactoryBean, BeanFactoryAware, BeanNameAware,
BeanClassLoaderAware, InitializingBean, Lifecycle, ApplicationListener<ContextRefreshedEvent> {
BeanClassLoaderAware, InitializingBean, SmartLifecycle {
private volatile MessageSource<?> source;
@@ -97,12 +94,6 @@ public class SourcePollingChannelAdapterFactoryBean implements FactoryBean, Bean
this.initializeAdapter();
}
public void onApplicationEvent(ContextRefreshedEvent event) {
if (this.adapter != null) {
this.adapter.onApplicationEvent(event);
}
}
public Object getObject() throws Exception {
if (this.adapter == null) {
this.initializeAdapter();
@@ -139,9 +130,7 @@ public class SourcePollingChannelAdapterFactoryBean implements FactoryBean, Bean
spca.setTransactionManager(this.pollerMetadata.getTransactionManager());
spca.setTransactionDefinition(this.pollerMetadata.getTransactionDefinition());
spca.setAdviceChain(this.pollerMetadata.getAdviceChain());
if (!this.autoStartup) {
spca.setStartupMode(StartupMode.MANUAL);
}
spca.setAutoStartup(this.autoStartup);
spca.setBeanName(this.beanName);
spca.setBeanFactory(this.beanFactory);
spca.setBeanClassLoader(this.beanClassLoader);
@@ -152,14 +141,19 @@ public class SourcePollingChannelAdapterFactoryBean implements FactoryBean, Bean
}
/*
* Lifecycle implementation (delegates to the created adapter).
* SmartLifecycle implementation (delegates to the created adapter)
*/
public boolean isAutoStartup() {
return (this.adapter != null) ? this.adapter.isAutoStartup() : true;
}
public int getPhase() {
return (this.adapter != null) ? this.adapter.getPhase() : 0;
}
public boolean isRunning() {
if (this.adapter == null) {
return false;
}
return this.adapter.isRunning();
return (this.adapter != null) ? this.adapter.isRunning() : false;
}
public void start() {
@@ -174,4 +168,10 @@ public class SourcePollingChannelAdapterFactoryBean implements FactoryBean, Bean
}
}
public void stop(Runnable callback) {
if (this.adapter != null) {
this.adapter.stop(callback);
}
}
}

View File

@@ -40,6 +40,8 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.Lifecycle;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.integration.annotation.Aggregator;
import org.springframework.integration.annotation.Router;
@@ -60,7 +62,7 @@ import org.springframework.util.StringUtils;
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class MessagingAnnotationPostProcessor implements BeanPostProcessor, BeanFactoryAware, InitializingBean, ApplicationListener {
public class MessagingAnnotationPostProcessor implements BeanPostProcessor, BeanFactoryAware, InitializingBean, Lifecycle, ApplicationListener {
private final Log logger = LogFactory.getLog(this.getClass());
@@ -70,7 +72,11 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
private final Map<Class<? extends Annotation>, MethodAnnotationPostProcessor<?>> postProcessors =
new HashMap<Class<? extends Annotation>, MethodAnnotationPostProcessor<?>>();
private Set<ApplicationListener> listeners = new HashSet<ApplicationListener>();
private final Set<ApplicationListener> listeners = new HashSet<ApplicationListener>();
private final Set<Lifecycle> lifecycles = new HashSet<Lifecycle>();
private volatile boolean running = true;
public void setBeanFactory(BeanFactory beanFactory) {
@@ -124,6 +130,12 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
throw new BeanInitializationException("failed to initialize annotated component", e);
}
}
if (result instanceof Lifecycle) {
lifecycles.add((Lifecycle) result);
if (result instanceof SmartLifecycle && ((SmartLifecycle) result).isAutoStartup()) {
((SmartLifecycle) result).start();
}
}
if (result instanceof ApplicationListener) {
listeners.add((ApplicationListener) result);
}
@@ -185,4 +197,29 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
}
}
// Lifecycle implementation
public boolean isRunning() {
return this.running;
}
public void start() {
for (Lifecycle lifecycle : this.lifecycles) {
if (!lifecycle.isRunning()) {
lifecycle.start();
}
}
this.running = true;
}
public void stop() {
for (Lifecycle lifecycle : this.lifecycles) {
if (lifecycle.isRunning()) {
lifecycle.stop();
}
}
this.running = false;
}
}

View File

@@ -20,10 +20,7 @@ import java.util.concurrent.locks.ReentrantLock;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.Lifecycle;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.SmartLifecycle;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.scheduling.TaskScheduler;
@@ -39,25 +36,23 @@ import org.springframework.scheduling.TaskScheduler;
*
* @author Mark Fisher
*/
public abstract class AbstractEndpoint extends IntegrationObjectSupport
implements ApplicationListener, Lifecycle, InitializingBean {
public abstract class AbstractEndpoint extends IntegrationObjectSupport implements SmartLifecycle, InitializingBean {
public static enum StartupMode {
MANUAL,
ON_INITIALIZATION,
ON_CONTEXT_REFRESH;
}
private volatile boolean autoStartup = true;
private volatile StartupMode startupMode = StartupMode.MANUAL;
private volatile int phase = 0;
private volatile boolean running;
private final ReentrantLock lifecycleLock = new ReentrantLock();
public void setStartupMode(StartupMode startupMode) {
this.startupMode = (startupMode != null ? startupMode : StartupMode.MANUAL);
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
public void setPhase(int phase) {
this.phase = phase;
}
public void setTaskScheduler(TaskScheduler taskScheduler) {
@@ -67,23 +62,21 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
public final void afterPropertiesSet() {
try {
this.onInit();
if (this.startupMode == StartupMode.ON_INITIALIZATION) {
this.start();
}
}
catch (Exception e) {
throw new BeanInitializationException("failed to initialize", e);
}
}
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent
&& this.startupMode == StartupMode.ON_CONTEXT_REFRESH) {
this.start();
}
// SmartLifecycle implementation
public final boolean isAutoStartup() {
return this.autoStartup;
}
// Lifecycle implementation
public final int getPhase() {
return this.phase;
}
public final boolean isRunning() {
this.lifecycleLock.lock();
@@ -127,6 +120,17 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
}
}
public final void stop(Runnable callback) {
this.lifecycleLock.lock();
try {
this.stop();
callback.run();
}
finally {
this.lifecycleLock.unlock();
}
}
protected void onInit() throws Exception {
}

View File

@@ -75,7 +75,7 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
public AbstractPollingEndpoint() {
this.setStartupMode(StartupMode.ON_CONTEXT_REFRESH);
this.setPhase(Integer.MAX_VALUE);
}

View File

@@ -36,9 +36,9 @@ public class EventDrivenConsumer extends AbstractEndpoint {
public EventDrivenConsumer(SubscribableChannel inputChannel, MessageHandler handler) {
Assert.notNull(inputChannel, "inputChannel must not be null");
Assert.notNull(handler, "handler must not be null");
this.setStartupMode(StartupMode.ON_INITIALIZATION);
this.inputChannel = inputChannel;
this.handler = handler;
this.setPhase(Integer.MIN_VALUE);
}

View File

@@ -39,7 +39,6 @@ public class PollingConsumer extends AbstractPollingEndpoint {
public PollingConsumer(PollableChannel inputChannel, MessageHandler handler) {
Assert.notNull(inputChannel, "inputChannel must not be null");
Assert.notNull(handler, "handler must not be null");
this.setStartupMode(StartupMode.ON_CONTEXT_REFRESH);
this.inputChannel = inputChannel;
this.handler = handler;
}

View File

@@ -51,8 +51,6 @@ public abstract class AbstractMessagingGateway extends AbstractEndpoint implemen
private volatile boolean shouldThrowErrors = true;
private volatile boolean autoStartup = true;
private volatile boolean initialized;
private volatile AbstractEndpoint replyMessageCorrelator;
@@ -109,23 +107,8 @@ public abstract class AbstractMessagingGateway extends AbstractEndpoint implemen
this.shouldThrowErrors = shouldThrowErrors;
}
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
@Override
protected void onInit() throws Exception {
if (this.autoStartup) {
if (this.requestChannel instanceof PollableChannel) {
this.setStartupMode(StartupMode.ON_CONTEXT_REFRESH);
}
else {
this.setStartupMode(StartupMode.ON_INITIALIZATION);
}
}
else {
this.setStartupMode(StartupMode.MANUAL);
}
this.initialized = true;
}

View File

@@ -30,10 +30,11 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@@ -108,17 +109,18 @@ import org.springframework.util.StringUtils;
*/
public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]>, OutboundMessageMapper<Object[]> {
private static GenericConversionService conversionService;
private static ConversionService conversionService;
static { // see INT-829
conversionService = new DefaultConversionService();
conversionService.removeConvertible(Object.class, Map.class);
conversionService.removeConvertible(Map.class, Object.class);
conversionService.removeConvertible(Object.class, String.class);
conversionService.addConverter(new Converter<Number, String>() {
conversionService = ConversionServiceFactory.createDefaultConversionService();
ConverterRegistry registry = (ConverterRegistry) conversionService;
registry.removeConvertible(Object.class, Map.class);
registry.removeConvertible(Map.class, Object.class);
registry.removeConvertible(Object.class, String.class);
registry.addConverter(new Converter<Number, String>() {
public String convert(Number source) {return null;}
});
conversionService.addConverter(new Converter<Date, String>() {
registry.addConverter(new Converter<Date, String>() {
public String convert(Date source) {return null;}
});
}

View File

@@ -25,7 +25,6 @@ import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.endpoint.AbstractEndpoint.StartupMode;
import org.springframework.integration.handler.MethodInvokingMessageHandler;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -49,7 +48,7 @@ public class MethodInvokingOutboundChannelAdapterParserTests {
assertEquals(MethodInvokingMessageHandler.class, handler.getClass());
DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(handler);
assertEquals(99, handlerAccessor.getPropertyValue("order"));
assertEquals(StartupMode.MANUAL, adapterAccessor.getPropertyValue("startupMode"));
assertEquals(Boolean.FALSE, adapterAccessor.getPropertyValue("autoStartup"));
}
@Test
@@ -60,7 +59,7 @@ public class MethodInvokingOutboundChannelAdapterParserTests {
assertEquals(MethodInvokingMessageHandler.class, handler.getClass());
DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(handler);
assertEquals(99, handlerAccessor.getPropertyValue("order"));
assertEquals(StartupMode.MANUAL, adapterAccessor.getPropertyValue("startupMode"));
assertEquals(Boolean.FALSE, adapterAccessor.getPropertyValue("autoStartup"));
}