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