No-arg gateway method can be a 'send' operation
- no-arg method will now be a send (instead of receive) if @Payload is present - added 'method' to the evaluation context variables with the String value of the invoked method's name - added test for new gateway no-arg method send option - enable 'payload-expression' in XML for no-arg methods - use per-method-invocation evaluation context for header expressions (provides 'args' and 'method' as context variables)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -30,6 +30,7 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
@@ -82,7 +83,7 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
|
||||
private final Map<String, Expression> parameterPayloadExpressions = new HashMap<String, Expression>();
|
||||
|
||||
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
|
||||
private final StandardEvaluationContext staticEvaluationContext = new StandardEvaluationContext();
|
||||
|
||||
private volatile BeanResolver beanResolver;
|
||||
|
||||
@@ -107,7 +108,7 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
public void setBeanFactory(final BeanFactory beanFactory) {
|
||||
if (beanFactory != null) {
|
||||
this.beanResolver = new BeanFactoryResolver(beanFactory);
|
||||
this.evaluationContext.setBeanResolver(beanResolver);
|
||||
this.staticEvaluationContext.setBeanResolver(beanResolver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,13 +126,9 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
Object messageOrPayload = null;
|
||||
boolean foundPayloadAnnotation = false;
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
EvaluationContext methodInvocationEvaluationContext = createMethodInvocationEvaluationContext(arguments);
|
||||
if (this.payloadExpression != null) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("args", arguments);
|
||||
if (this.beanResolver != null) {
|
||||
context.setBeanResolver(this.beanResolver);
|
||||
}
|
||||
messageOrPayload = this.payloadExpression.getValue(context);
|
||||
messageOrPayload = this.payloadExpression.getValue(methodInvocationEvaluationContext);
|
||||
}
|
||||
for (int i = 0; i < this.parameterList.size(); i++) {
|
||||
Object argumentValue = arguments[i];
|
||||
@@ -195,7 +192,7 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
if (!CollectionUtils.isEmpty(this.headerExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = new HashMap<String, Object>();
|
||||
for (Map.Entry<String, Expression> entry : this.headerExpressions.entrySet()) {
|
||||
Object value = entry.getValue().getValue(this.evaluationContext);
|
||||
Object value = entry.getValue().getValue(methodInvocationEvaluationContext);
|
||||
if (value != null) {
|
||||
evaluatedHeaders.put(entry.getKey(), value);
|
||||
}
|
||||
@@ -205,13 +202,23 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private StandardEvaluationContext createMethodInvocationEvaluationContext(Object[] arguments) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("args", arguments);
|
||||
context.setVariable("method", this.method.getName());
|
||||
if (this.beanResolver != null) {
|
||||
context.setBeanResolver(this.beanResolver);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private Object evaluatePayloadExpression(String expressionString, Object argumentValue) {
|
||||
Expression expression = this.parameterPayloadExpressions.get(expressionString);
|
||||
if (expression == null) {
|
||||
expression = PARSER.parseExpression(expressionString);
|
||||
this.parameterPayloadExpressions.put(expressionString, expression);
|
||||
}
|
||||
return expression.getValue(this.evaluationContext, argumentValue);
|
||||
return expression.getValue(this.staticEvaluationContext, argumentValue);
|
||||
}
|
||||
|
||||
private Annotation findMappingAnnotation(Annotation[] annotations) {
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.concurrent.Future;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
@@ -45,6 +44,7 @@ import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.Payload;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.endpoint.AbstractEndpoint;
|
||||
import org.springframework.integration.history.TrackableComponent;
|
||||
@@ -285,7 +285,13 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
boolean shouldReply = returnType != void.class;
|
||||
int paramCount = method.getParameterTypes().length;
|
||||
Object response = null;
|
||||
if (paramCount == 0) {
|
||||
boolean hasPayloadExpression = method.isAnnotationPresent(Payload.class);
|
||||
if (!hasPayloadExpression && this.methodMetadataMap != null) {
|
||||
// check for the method metadata next
|
||||
GatewayMethodMetadata metadata = this.methodMetadataMap.get(method.getName());
|
||||
hasPayloadExpression = (metadata != null) && StringUtils.hasText(metadata.getPayloadExpression());
|
||||
}
|
||||
if (paramCount == 0 && !hasPayloadExpression) {
|
||||
if (shouldReply) {
|
||||
if (shouldReturnMessage) {
|
||||
return gateway.receive();
|
||||
|
||||
@@ -213,6 +213,20 @@ public class GatewayProxyFactoryBeanTests {
|
||||
assertEquals("foobar", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoArgMethodWithPayloadAnnotation() throws Exception {
|
||||
QueueChannel requestChannel = new QueueChannel();
|
||||
startResponder(requestChannel);
|
||||
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
|
||||
proxyFactory.setServiceInterface(TestService.class);
|
||||
proxyFactory.setDefaultRequestChannel(requestChannel);
|
||||
proxyFactory.setBeanName("testGateway");
|
||||
proxyFactory.afterPropertiesSet();
|
||||
TestService service = (TestService) proxyFactory.getObject();
|
||||
String result = service.requestReplyWithPayloadAnnotation();
|
||||
assertEquals("requestReplyWithPayloadAnnotation0bar", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageAsReturnValue() throws Exception {
|
||||
final QueueChannel requestChannel = new QueueChannel();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<int:gateway id="gateway" service-interface="org.springframework.integration.gateway.GatewayWithPayloadExpressionTests$SampleGateway">
|
||||
<int:method name="send1" request-channel="input" payload-expression="#args[0] + 'bar'"/>
|
||||
<int:method name="send2" request-channel="input" payload-expression="@testBean.sum(#args[0])"/>
|
||||
<int:method name="send3" request-channel="input" payload-expression="#method"/>
|
||||
</int:gateway>
|
||||
|
||||
<int:gateway id="annotatedGateway"
|
||||
|
||||
@@ -67,12 +67,21 @@ public class GatewayWithPayloadExpressionTests {
|
||||
assertEquals("foobar", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArgMethodWithPayloadExpression() throws Exception {
|
||||
gateway.send3();
|
||||
Message<?> result = input.receive(0);
|
||||
assertEquals("send3", result.getPayload());
|
||||
}
|
||||
|
||||
|
||||
public static interface SampleGateway {
|
||||
|
||||
void send1(String value);
|
||||
|
||||
void send2(String value);
|
||||
|
||||
void send3();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.gateway;
|
||||
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.annotation.Payload;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -38,4 +39,7 @@ public interface TestService {
|
||||
|
||||
Message<?> requestReplyWithMessageReturnValue(String input);
|
||||
|
||||
@Payload("#method + #args.length")
|
||||
String requestReplyWithPayloadAnnotation();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user