Removing the @Poller annotation. Now, any Annotation-based endpoint must have a SubscribableChannel reference for its inputChannel. If necessary, the new <bridge/> element can be used to convert PollableChannels to SubscribableChannels.

This commit is contained in:
Mark Fisher
2008-11-25 19:45:16 +00:00
parent 1f0104d6f8
commit 0e5b4bcb50
18 changed files with 17 additions and 867 deletions

View File

@@ -22,9 +22,6 @@ import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
import org.springframework.transaction.annotation.Transactional;
/**
* Annotation that can be specified at method-level alongside a Message Endpoint
@@ -39,22 +36,4 @@ import org.springframework.transaction.annotation.Transactional;
@Documented
public @interface Poller {
int interval();
long initialDelay() default 0;
boolean fixedRate() default false;
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
int maxMessagesPerPoll() default -1;
String taskExecutor() default "";
Transactional transactionAttributes() default @Transactional;
String transactionManager() default "";
String[] adviceChain() default {};
}

View File

@@ -23,14 +23,11 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.generic.GenericBeanFactoryAccessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.channel.BeanFactoryChannelResolver;
import org.springframework.integration.channel.ChannelResolver;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.PollingConsumer;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.message.MessageHandler;
import org.springframework.util.Assert;
@@ -60,8 +57,7 @@ public abstract class AbstractMethodAnnotationPostProcessor<T extends Annotation
public Object postProcess(Object bean, String beanName, Method method, T annotation) {
MessageHandler handler = this.createHandler(bean, method, annotation);
Poller pollerAnnotation = AnnotationUtils.findAnnotation(method, Poller.class);
AbstractEndpoint endpoint = this.createEndpoint(handler, annotation, pollerAnnotation);
AbstractEndpoint endpoint = this.createEndpoint(handler, annotation);
if (endpoint != null) {
return endpoint;
}
@@ -72,29 +68,15 @@ public abstract class AbstractMethodAnnotationPostProcessor<T extends Annotation
return (StringUtils.hasText((String) AnnotationUtils.getValue(annotation, INPUT_CHANNEL_ATTRIBUTE)));
}
private AbstractEndpoint createEndpoint(MessageHandler handler, T annotation, Poller pollerAnnotation) {
private AbstractEndpoint createEndpoint(MessageHandler handler, T annotation) {
AbstractEndpoint endpoint = null;
String inputChannelName = (String) AnnotationUtils.getValue(annotation, INPUT_CHANNEL_ATTRIBUTE);
if (StringUtils.hasText(inputChannelName)) {
MessageChannel inputChannel = this.channelResolver.resolveChannelName(inputChannelName);
Assert.notNull(inputChannel, "failed to resolve inputChannel '" + inputChannelName + "'");
if (inputChannel instanceof PollableChannel) {
PollingConsumer pollingEndpoint = new PollingConsumer(
(PollableChannel) inputChannel, handler);
if (pollerAnnotation != null) {
AnnotationConfigUtils.configurePollingEndpointWithPollerAnnotation(
pollingEndpoint, pollerAnnotation, this.beanFactoryAccessor.getBeanFactory());
}
endpoint = pollingEndpoint;
}
else if (inputChannel instanceof SubscribableChannel) {
Assert.isTrue(pollerAnnotation == null,
"The @Poller annotation should only be provided for a PollableChannel");
endpoint = new EventDrivenConsumer((SubscribableChannel) inputChannel, handler);
}
else {
throw new IllegalArgumentException("unsupported channel type: [" + inputChannel.getClass() + "]");
}
Assert.isInstanceOf(SubscribableChannel.class, inputChannel,
"The input channel for an Annotation-based endpoint must be a SubscribableChannel.");
endpoint = new EventDrivenConsumer((SubscribableChannel) inputChannel, handler);
if (handler instanceof BeanFactoryAware) {
((BeanFactoryAware) handler).setBeanFactory(this.beanFactoryAccessor.getBeanFactory());
}

View File

@@ -1,87 +0,0 @@
/*
* 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.integration.config.annotation;
import java.util.ArrayList;
import java.util.List;
import org.aopalliance.aop.Advice;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.endpoint.AbstractPollingEndpoint;
import org.springframework.integration.scheduling.IntervalTrigger;
import org.springframework.integration.scheduling.Trigger;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.SpringTransactionAnnotationParser;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Utility methods for working with annotations on Messaging components.
*
* @author Mark Fisher
*/
public abstract class AnnotationConfigUtils {
public static void configurePollingEndpointWithPollerAnnotation(
AbstractPollingEndpoint endpoint, Poller pollerAnnotation, BeanFactory beanFactory) {
Trigger trigger = parseTriggerFromPollerAnnotation(pollerAnnotation);
endpoint.setTrigger(trigger);
endpoint.setMaxMessagesPerPoll(pollerAnnotation.maxMessagesPerPoll());
if (StringUtils.hasText(pollerAnnotation.transactionManager())) {
String txManagerRef = pollerAnnotation.transactionManager();
Assert.isTrue(beanFactory.containsBean(txManagerRef),
"failed to resolve transactionManager reference, no such bean '" + txManagerRef + "'");
PlatformTransactionManager txManager = (PlatformTransactionManager)
beanFactory.getBean(txManagerRef, PlatformTransactionManager.class);
endpoint.setTransactionManager(txManager);
Transactional txAnnotation = pollerAnnotation.transactionAttributes();
SpringTransactionAnnotationParser txParser = new SpringTransactionAnnotationParser();
endpoint.setTransactionDefinition(txParser.parseTransactionAnnotation(txAnnotation));
}
if (StringUtils.hasText(pollerAnnotation.taskExecutor())) {
String taskExecutorRef = pollerAnnotation.taskExecutor();
Assert.isTrue(beanFactory.containsBean(taskExecutorRef),
"failed to resolve taskExecutor reference, no such bean '" + taskExecutorRef + "'");
TaskExecutor taskExecutor = (TaskExecutor) beanFactory.getBean(taskExecutorRef, TaskExecutor.class);
endpoint.setTaskExecutor(taskExecutor);
}
String[] adviceChainArray = pollerAnnotation.adviceChain();
if (adviceChainArray.length > 0) {
List<Advice> adviceChain = new ArrayList<Advice>();
for (String adviceChainString : adviceChainArray) {
String[] adviceRefs = StringUtils.tokenizeToStringArray(adviceChainString, ",");
for (String adviceRef : adviceRefs) {
adviceChain.add((Advice) beanFactory.getBean(adviceRef, Advice.class));
}
}
endpoint.setAdviceChain(adviceChain);
}
}
public static Trigger parseTriggerFromPollerAnnotation(Poller pollerAnnotation) {
IntervalTrigger trigger = new IntervalTrigger(
pollerAnnotation.interval(), pollerAnnotation.timeUnit());
trigger.setInitialDelay(pollerAnnotation.initialDelay());
trigger.setFixedRate(pollerAnnotation.fixedRate());
return trigger;
}
}

View File

@@ -29,17 +29,13 @@ import org.springframework.integration.channel.BeanFactoryChannelResolver;
import org.springframework.integration.channel.ChannelResolutionException;
import org.springframework.integration.channel.ChannelResolver;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.SubscribableChannel;
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.SourcePollingChannelAdapter;
import org.springframework.integration.handler.MethodInvokingMessageHandler;
import org.springframework.integration.message.MethodInvokingMessageSource;
import org.springframework.integration.scheduling.IntervalTrigger;
import org.springframework.integration.scheduling.Trigger;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -120,24 +116,13 @@ public class ChannelAdapterAnnotationPostProcessor implements MethodAnnotationPo
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
adapter.setSource(source);
adapter.setOutputChannel(channel);
AnnotationConfigUtils.configurePollingEndpointWithPollerAnnotation(
adapter, pollerAnnotation, this.beanFactory);
return adapter;
}
private AbstractEndpoint createOutboundChannelAdapter(MessageChannel channel, MethodInvokingMessageHandler handler, Poller pollerAnnotation) {
if (channel instanceof PollableChannel) {
Trigger trigger = (pollerAnnotation != null)
? AnnotationConfigUtils.parseTriggerFromPollerAnnotation(pollerAnnotation)
: new IntervalTrigger(0);
PollingConsumer endpoint = new PollingConsumer((PollableChannel) channel, handler);
endpoint.setTrigger(trigger);
return endpoint;
}
if (channel instanceof SubscribableChannel) {
return new EventDrivenConsumer((SubscribableChannel) channel, handler);
}
return null;
Assert.isInstanceOf(SubscribableChannel.class, channel,
"The input channel for an Annotation-based endpoint must be a SubscribableChannel.");
return new EventDrivenConsumer((SubscribableChannel) channel, handler);
}
private boolean hasReturnValue(Method method) {