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:
@@ -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 {};
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user