Removed the "NEXT_TARGET" header, since it is no longer used by the Router implementations. Also, the MessagingAnnotationPostProcessor now considers any component annotated with a "stereotype" as a candidate for post-processing.

This commit is contained in:
Mark Fisher
2008-08-28 20:49:45 +00:00
parent ba9c086aea
commit 37b4ee5bd7
8 changed files with 128 additions and 186 deletions

View File

@@ -16,7 +16,11 @@
package org.springframework.integration.config.annotation;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.aop.support.AopUtils;
@@ -37,6 +41,7 @@ import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.message.MessageSource;
import org.springframework.integration.message.MessageTarget;
import org.springframework.integration.scheduling.PollingSchedule;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
/**
@@ -81,10 +86,11 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Init
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Object originalBean = bean;
Class<?> beanClass = this.getBeanClass(bean);
MessageEndpoint endpointAnnotation = AnnotationUtils.findAnnotation(beanClass, MessageEndpoint.class);
if (endpointAnnotation == null) {
if (!this.isStereotype(beanClass)) {
// we only post-process stereotype components
return bean;
}
MessageEndpoint endpointAnnotation = AnnotationUtils.findAnnotation(beanClass, MessageEndpoint.class);
for (Map.Entry<Class<?>, AnnotationMethodPostProcessor> entry : this.postProcessors.entrySet()) {
AnnotationMethodPostProcessor postProcessor = entry.getValue();
bean = postProcessor.postProcess(bean, beanName, beanClass);
@@ -138,4 +144,19 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Init
return (targetClass != null) ? targetClass : bean.getClass();
}
private boolean isStereotype(Class<?> beanClass) {
List<Annotation> annotations = new ArrayList<Annotation>(Arrays.asList(beanClass.getAnnotations()));
Class<?>[] interfaces = beanClass.getInterfaces();
for (Class<?> iface : interfaces) {
annotations.addAll(Arrays.asList(iface.getAnnotations()));
}
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if (annotationType.equals(Component.class) || annotationType.isAnnotationPresent(Component.class)) {
return true;
}
}
return false;
}
}

View File

@@ -44,14 +44,12 @@ import org.springframework.util.Assert;
*
* <p>The reply target is resolved according to the following order:
* <ol>
* <li>the 'nextTarget' header value of the reply Message</li>
* <li>the 'outputChannel' of this Message Endpoint</li>
* <li>the 'returnAddress' header value of the request Message</li>
* </ol>
* For the 'nextTarget' and 'returnAddress' values, either a
* {@link MessageTarget} instance or String is accepted. If the
* value is a String, then the endpoint will consult its
* {@link ChannelRegistry} (typically provided by the MessageBus).
* For the 'returnAddress' value, either a {@link MessageTarget} instance
* or String is accepted. If the value is a String, then the endpoint will
* consult its {@link ChannelRegistry} (typically provided by the MessageBus).
* If no reply target can be determined for a non-null reply Message,
* a {@link MessageEndpointReplyException} will be thrown.
*
@@ -150,7 +148,6 @@ public class DefaultEndpoint<T extends MessageHandler> extends AbstractRequestRe
replyMessage = MessageBuilder.fromMessage(replyMessage)
.copyHeadersIfAbsent(requestMessage.getHeaders())
.setHeaderIfAbsent(MessageHeaders.CORRELATION_ID, requestMessage.getHeaders().getId())
.setNextTarget((String)null)
.build();
if (!this.getMessageExchangeTemplate().send(replyMessage, replyTarget)) {
throw new MessageEndpointReplyException(replyMessage, requestMessage,
@@ -201,26 +198,18 @@ public class DefaultEndpoint<T extends MessageHandler> extends AbstractRequestRe
}
private MessageTarget resolveReplyTarget(Message<?> replyMessage, MessageHeaders requestHeaders) {
MessageTarget replyTarget = this.resolveTargetAttribute(replyMessage.getHeaders().getNextTarget());
MessageTarget replyTarget = this.getTarget();
if (replyTarget == null) {
replyTarget = this.getTarget();
}
if (replyTarget == null) {
replyTarget = this.resolveTargetAttribute(requestHeaders.getReturnAddress());
}
return replyTarget;
}
private MessageTarget resolveTargetAttribute(Object targetAttribute) {
MessageTarget replyTarget = null;
if (targetAttribute != null) {
if (targetAttribute instanceof MessageTarget) {
replyTarget = (MessageTarget) targetAttribute;
}
else if (targetAttribute instanceof String) {
ChannelRegistry registry = this.getChannelRegistry();
if (registry != null) {
replyTarget = registry.lookupChannel((String) targetAttribute);
Object returnAddress = requestHeaders.getReturnAddress();
if (returnAddress != null) {
if (returnAddress instanceof MessageTarget) {
replyTarget = (MessageTarget) returnAddress;
}
else if (returnAddress instanceof String) {
ChannelRegistry registry = this.getChannelRegistry();
if (registry != null) {
replyTarget = registry.lookupChannel((String) returnAddress);
}
}
}
}
@@ -228,8 +217,7 @@ public class DefaultEndpoint<T extends MessageHandler> extends AbstractRequestRe
}
/**
* Specify the channel where reply Messages should be sent if
* no 'nextTarget' header value is available on the reply Message.
* Specify the channel where reply Messages should be sent.
*/
public void setOutputChannel(MessageChannel outputChannel) {
this.setTarget(outputChannel);

View File

@@ -146,14 +146,6 @@ public final class MessageBuilder<T> {
return this.setHeader(MessageHeaders.CORRELATION_ID, correlationId);
}
public MessageBuilder<T> setNextTarget(MessageTarget nextTarget) {
return this.setHeader(MessageHeaders.NEXT_TARGET, nextTarget);
}
public MessageBuilder<T> setNextTarget(String nextTarget) {
return this.setHeader(MessageHeaders.NEXT_TARGET, nextTarget);
}
public MessageBuilder<T> setReturnAddress(MessageTarget returnAddress) {
return this.setHeader(MessageHeaders.RETURN_ADDRESS, returnAddress);
}

View File

@@ -38,8 +38,6 @@ public final class MessageHeaders implements Map<String, Object>, Serializable {
public static final String CORRELATION_ID = "internal.header.correlationId";
public static final String NEXT_TARGET = "internal.header.nextTarget";
public static final String RETURN_ADDRESS = "internal.header.returnAddress";
public static final String EXPIRATION_DATE = "internal.header.exprirationDate";
@@ -82,10 +80,6 @@ public final class MessageHeaders implements Map<String, Object>, Serializable {
return this.get(RETURN_ADDRESS);
}
public Object getNextTarget() {
return this.get(NEXT_TARGET);
}
public Integer getSequenceNumber() {
Integer sequenceNumber = this.get(SEQUENCE_NUMBER, Integer.class);
return (sequenceNumber != null ? sequenceNumber : 0);