INT-670 added BeanResolver to context for SpEL evaluation on method-level @Payload annotations for Gateway

This commit is contained in:
Mark Fisher
2010-07-23 03:13:57 +00:00
parent 4c6d5fd752
commit 91bb24b102
3 changed files with 53 additions and 4 deletions

View File

@@ -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) {

View File

@@ -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++) {

View File

@@ -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() + "!!!";
}
}
}