INT-670 added BeanResolver to context for SpEL evaluation on method-level @Payload annotations for Gateway
This commit is contained in:
@@ -296,6 +296,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
|
||||
}
|
||||
}
|
||||
ArgumentArrayMessageMapper messageMapper = new ArgumentArrayMessageMapper(method, staticHeaders);
|
||||
messageMapper.setBeanFactory(this.getBeanFactory());
|
||||
SimpleMessagingGateway gateway = new SimpleMessagingGateway(messageMapper, new SimpleMessageMapper());
|
||||
gateway.setExceptionMapper(exceptionMapper);
|
||||
if (this.getTaskScheduler() != null) {
|
||||
|
||||
@@ -23,9 +23,14 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.AccessException;
|
||||
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;
|
||||
@@ -97,19 +102,21 @@ import org.springframework.util.StringUtils;
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]> {
|
||||
public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]>, BeanFactoryAware {
|
||||
|
||||
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
|
||||
|
||||
|
||||
private final Map<String, Object> staticHeaders;
|
||||
|
||||
private final Method method;
|
||||
|
||||
private final Map<String, Object> staticHeaders;
|
||||
|
||||
private final List<MethodParameter> parameterList;
|
||||
|
||||
private final Expression payloadExpression;
|
||||
|
||||
private volatile BeanResolver beanResolver;
|
||||
|
||||
|
||||
public ArgumentArrayMessageMapper(Method method) {
|
||||
this(method, null);
|
||||
@@ -124,7 +131,17 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
|
||||
}
|
||||
|
||||
|
||||
public Message<?> toMessage(Object[] arguments) {
|
||||
public void setBeanFactory(final BeanFactory beanFactory) {
|
||||
if (beanFactory != null) {
|
||||
this.beanResolver = new BeanResolver() {
|
||||
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
|
||||
return beanFactory.getBean(beanName);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Message<?> toMessage(Object[] arguments) {
|
||||
Assert.notNull(arguments, "cannot map null arguments to Message");
|
||||
if (arguments.length != this.parameterList.size()) {
|
||||
String prefix = (arguments.length < this.parameterList.size()) ? "Not enough" : "Too many";
|
||||
@@ -142,6 +159,9 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
|
||||
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);
|
||||
}
|
||||
for (int i = 0; i < this.parameterList.size(); i++) {
|
||||
|
||||
@@ -26,6 +26,8 @@ import java.util.Map;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.integration.annotation.Header;
|
||||
import org.springframework.integration.annotation.Headers;
|
||||
import org.springframework.integration.annotation.Payload;
|
||||
@@ -126,6 +128,21 @@ public class GatewayProxyMessageMappingTests {
|
||||
assertEquals("foobar!", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadAnnotationAtMethodLevelUsingBeanResolver() throws Exception {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
RootBeanDefinition gatewayDefinition = new RootBeanDefinition(GatewayProxyFactoryBean.class);
|
||||
gatewayDefinition.getPropertyValues().add("defaultRequestChannel", channel);
|
||||
gatewayDefinition.getPropertyValues().add("serviceInterface", TestGateway.class);
|
||||
context.registerBeanDefinition("testGateway", gatewayDefinition);
|
||||
context.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
|
||||
context.refresh();
|
||||
TestGateway gateway = context.getBean("testGateway", TestGateway.class);
|
||||
gateway.payloadAnnotationAtMethodLevelUsingBeanResolver("foo");
|
||||
Message<?> result = channel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("FOO!!!", result.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected = MessagingException.class)
|
||||
public void twoMapsWithoutAnnotations() {
|
||||
@@ -172,6 +189,9 @@ public class GatewayProxyMessageMappingTests {
|
||||
@Payload("#args[0] + #args[1] + '!'")
|
||||
void payloadAnnotationAtMethodLevel(String a, String b);
|
||||
|
||||
@Payload("@testBean.exclaim(#args[0])")
|
||||
void payloadAnnotationAtMethodLevelUsingBeanResolver(String s);
|
||||
|
||||
// invalid
|
||||
void twoMapsWithoutAnnotations(Map<String, Object> m1, Map<String, Object> m2);
|
||||
|
||||
@@ -189,4 +209,12 @@ public class GatewayProxyMessageMappingTests {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
public String exclaim(String s) {
|
||||
return s.toUpperCase() + "!!!";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user