Removed the @Poller annotation (since configuration metadata should be externalized). Updated ChannelAdapterAnnotationPostProcessor. Only outbound Channel Adapters can be configured with annotations now that @Poller is no longer available. We may add a "poller" attribute to the @ChannelAdapter for providing a reference. That would enable annotation-based inbound adapters. However, the XML support (the <inbound-channel-adapter/> element) is pretty trivial, so this should not be necessrary.Otherwise, the @ChannelAdapter may actually be removed altogether since a @ServiceActivator annotation can be used for any outbound Method (even when no return-value is expected).
This commit is contained in:
@@ -1,39 +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.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation that can be specified at method-level alongside a Message Endpoint
|
||||
* annotation (e.g. @Splitter, @ChannelAdapter, etc.) in order to provide the
|
||||
* polling metadata and scheduling information for that endpoint.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface Poller {
|
||||
|
||||
}
|
||||
@@ -18,24 +18,16 @@ package org.springframework.integration.config.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.integration.annotation.ChannelAdapter;
|
||||
import org.springframework.integration.annotation.Poller;
|
||||
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.SubscribableChannel;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.endpoint.AbstractEndpoint;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.handler.MethodInvokingMessageHandler;
|
||||
import org.springframework.integration.message.MethodInvokingMessageSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -60,41 +52,21 @@ public class ChannelAdapterAnnotationPostProcessor implements MethodAnnotationPo
|
||||
|
||||
public Object postProcess(Object bean, String beanName, Method method, ChannelAdapter annotation) {
|
||||
Assert.notNull(this.beanFactory, "BeanFactory must not be null");
|
||||
AbstractEndpoint endpoint = null;
|
||||
MessageChannel channel = this.resolveOrCreateChannel(annotation.value());
|
||||
Poller pollerAnnotation = AnnotationUtils.findAnnotation(method, Poller.class);
|
||||
if (method.getParameterTypes().length == 0 && hasReturnValue(method)) {
|
||||
MethodInvokingMessageSource source = new MethodInvokingMessageSource();
|
||||
source.setObject(bean);
|
||||
source.setMethod(method);
|
||||
endpoint = this.createInboundChannelAdapter(source, channel, pollerAnnotation);
|
||||
}
|
||||
else if (method.getParameterTypes().length > 0 && !hasReturnValue(method)) {
|
||||
MethodInvokingMessageHandler handler = new MethodInvokingMessageHandler(bean, method);
|
||||
endpoint = this.createOutboundChannelAdapter(channel, handler, pollerAnnotation);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("The @ChannelAdapter can only be applied to methods"
|
||||
+ " that accept no arguments but have a return value (inbound) or methods that"
|
||||
+ " have no return value but do accept arguments (outbound).");
|
||||
}
|
||||
if (endpoint != null) {
|
||||
String annotationName = ClassUtils.getShortNameAsProperty(annotation.annotationType());
|
||||
String endpointName = beanName + "." + method.getName() + "." + annotationName;
|
||||
this.beanFactory.registerSingleton(endpointName, endpoint);
|
||||
// TODO: move this to IntegrationContextUtils?... common with MAPP
|
||||
if (endpoint instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) endpoint).setBeanFactory(beanFactory);
|
||||
}
|
||||
if (endpoint instanceof InitializingBean) {
|
||||
try {
|
||||
((InitializingBean) endpoint).afterPropertiesSet();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new BeanInitializationException("failed to initialize annotated channel adapter", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.isInstanceOf(SubscribableChannel.class, channel,
|
||||
"The channel for an Annotation-based Channel Adapter must be a SubscribableChannel.");
|
||||
Assert.isTrue(method.getParameterTypes().length > 0,
|
||||
"A method annotated with @ChannelAdapter must accept at least one argument.");
|
||||
Assert.isTrue(!hasReturnValue(method),
|
||||
"A method annotated with @ChannelAdapter must not have a return value."
|
||||
+ " Consider using a @ServiceActivator if a reply Message is expected.");
|
||||
MethodInvokingMessageHandler handler = new MethodInvokingMessageHandler(bean, method);
|
||||
EventDrivenConsumer endpoint = new EventDrivenConsumer((SubscribableChannel) channel, handler);
|
||||
String annotationName = ClassUtils.getShortNameAsProperty(annotation.annotationType());
|
||||
String endpointName = beanName + "." + method.getName() + "." + annotationName;
|
||||
this.beanFactory.registerSingleton(endpointName, endpoint);
|
||||
endpoint.setBeanFactory(beanFactory);
|
||||
endpoint.afterPropertiesSet();
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -110,21 +82,6 @@ public class ChannelAdapterAnnotationPostProcessor implements MethodAnnotationPo
|
||||
}
|
||||
}
|
||||
|
||||
private SourcePollingChannelAdapter createInboundChannelAdapter(MethodInvokingMessageSource source, MessageChannel channel, Poller pollerAnnotation) {
|
||||
Assert.notNull(pollerAnnotation, "The @Poller annotation is required (at method-level) "
|
||||
+ "when using the @ChannelAdapter annotation with a no-arg method.");
|
||||
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
|
||||
adapter.setSource(source);
|
||||
adapter.setOutputChannel(channel);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private AbstractEndpoint createOutboundChannelAdapter(MessageChannel channel, MethodInvokingMessageHandler handler, Poller pollerAnnotation) {
|
||||
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) {
|
||||
return !method.getReturnType().equals(void.class);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user