INT-1243 (refactoring publishing-interceptor) Step 2: removed "payload" attribute from @Publisher. The @Payload annotation now may be used either at method-level or on a single parameter.

This commit is contained in:
Mark Fisher
2010-07-20 16:10:45 +00:00
parent a94a5db38f
commit ecd0f34b3c
8 changed files with 75 additions and 32 deletions

View File

@@ -34,7 +34,7 @@ import java.lang.annotation.Target;
* @author Oleg Zhurakousky
* @since 2.0
*/
@Target(ElementType.PARAMETER)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Payload {

View File

@@ -27,6 +27,7 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -62,7 +63,28 @@ public class MethodAnnotationExpressionSource implements ExpressionSource {
}
public String getPayloadExpression(Method method) {
return this.getAnnotationValue(method, "payload", String.class);
String payloadExpression = null;
method.getAnnotation(Payload.class);
Payload methodPayloadAnnotation = AnnotationUtils.findAnnotation(method, Payload.class);
if (methodPayloadAnnotation != null) {
payloadExpression = StringUtils.hasText(methodPayloadAnnotation.value())
? methodPayloadAnnotation.value()
: "#" + this.getReturnValueVariableName(method);
}
Annotation[][] annotationArray = method.getParameterAnnotations();
for (int i = 0; i < annotationArray.length; i++) {
Annotation[] parameterAnnotations = annotationArray[i];
for (Annotation currentAnnotation : parameterAnnotations) {
if (Payload.class.equals(currentAnnotation.annotationType())) {
Assert.state(payloadExpression == null,
"@Payload can be used at most once on a @Publisher method, either at method-level or on a single parameter");
Assert.state("".equals(((Payload) currentAnnotation).value()),
"@Payload on a parameter for a @Publisher method may not contain an expression");
payloadExpression = "#" + this.getArgumentMapVariableName(method) + "[" + i + "]";
}
}
}
return payloadExpression;
}
public Map<String, String> getHeaderExpressions(Method method) {

View File

@@ -23,8 +23,8 @@ import java.lang.annotation.Target;
/**
* Annotation to indicate that a method, or all public methods if applied at
* class-level, should publish Messages whose payloads will be determined by
* the provided EL expression.
* class-level, should publish Messages. The @Payload and @Header annotations
* can be used in conjunction with this to determine the content of the Message.
*
* @author Mark Fisher
* @since 2.0
@@ -33,13 +33,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
public @interface Publisher {
/**
* String representation of a Spel Expression to evaluate when creating the
* Message payload. The default will be empty, thereby causing the return
* value to be used as the payload.
*/
String payload() default "";
/**
* Name of the Message Channel to which Messages will be published.
*/

View File

@@ -23,6 +23,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.Message;
import org.springframework.test.context.ContextConfiguration;
@@ -69,7 +70,8 @@ public class AnnotationConfigRegistrationTests {
public static class TestBean {
@Publisher(channel="testChannel", payload="#return + #args.lname")
@Publisher(channel="testChannel")
@Payload("#return + #args.lname")
public String setName(String fname, String lname, @Header("x") int num) {
return fname + " " + lname;
}

View File

@@ -16,13 +16,15 @@
package org.springframework.integration.aop;
import junit.framework.Assert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.Message;
import org.springframework.test.context.ContextConfiguration;
@@ -46,34 +48,51 @@ public class MessagePublishingAnnotationUsageTests {
@Test
public void headerWithExplicitName() {
String name = testBean.setName1("John", "Doe");
Assert.assertNotNull(name);
String name = testBean.defaultPayload("John", "Doe");
assertNotNull(name);
Message<?> message = channel.receive(1000);
Assert.assertNotNull(message);
Assert.assertEquals("John Doe", message.getPayload());
Assert.assertEquals("Doe", message.getHeaders().get("last"));
assertNotNull(message);
assertEquals("John Doe", message.getPayload());
assertEquals("Doe", message.getHeaders().get("last"));
}
@Test
public void headerWithImplicitName() {
String name = testBean.setName2("John", "Doe");
Assert.assertNotNull(name);
String name = testBean.defaultPayloadButExplicitAnnotation("John", "Doe");
assertNotNull(name);
Message<?> message = channel.receive(1000);
Assert.assertNotNull(message);
Assert.assertEquals("John Doe", message.getPayload());
Assert.assertEquals("Doe", message.getHeaders().get("lname"));
assertNotNull(message);
assertEquals("John Doe", message.getPayload());
assertEquals("Doe", message.getHeaders().get("lname"));
}
@Test
public void payloadAsArgument() {
String name = testBean.argumentAsPayload("John", "Doe");
assertNotNull(name);
assertEquals("John Doe", name);
Message<?> message = channel.receive(1000);
assertNotNull(message);
assertEquals("John", message.getPayload());
assertEquals("Doe", message.getHeaders().get("lname"));
}
public static class TestBean {
@Publisher(channel="testChannel", payload="#return")
public String setName1(String fname, @Header("last") String lname) {
@Publisher(channel="testChannel")
public String defaultPayload(String fname, @Header("last") String lname) {
return fname + " " + lname;
}
@Publisher(channel="testChannel", payload="#return")
public String setName2(String fname, @Header String lname) {
@Publisher(channel="testChannel")
@Payload
public String defaultPayloadButExplicitAnnotation(String fname, @Header String lname) {
return fname + " " + lname;
}
@Publisher(channel="testChannel")
public String argumentAsPayload(@Payload String fname, @Header String lname) {
return fname + " " + lname;
}
}

View File

@@ -24,6 +24,8 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.integration.annotation.Payload;
/**
* @author Mark Fisher
* @since 2.0
@@ -79,15 +81,18 @@ public class MethodAnnotationExpressionSourceTests {
}
@Publisher(payload="testExpression1")
@Publisher
@Payload("testExpression1")
public void methodWithExpressionAnnotationOnly(String arg1, int arg2) {
}
@Publisher(payload="#return", channel="foo")
@Publisher(channel="foo")
@Payload
public void methodWithChannelAndReturnAsPayload() {
}
@Publisher(payload="testExpression2")
@Publisher
@Payload("testExpression2")
@ExpressionBinding(argumentVariableNames="s, i", argumentMapVariableName="argz",
exceptionVariableName="x", returnValueVariableName="result")
public void methodWithExpressionBinding(String arg1, int arg2) {

View File

@@ -66,7 +66,7 @@ public class PublisherAnnotationAdvisorTests {
static class TestBeanImpl implements TestBean {
@Publisher(payload="#return")
@Publisher
public String test() {
return "foo";
}

View File

@@ -25,6 +25,7 @@ import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.Message;
@@ -67,7 +68,8 @@ public class PublisherExpressionTests {
static class TestBeanImpl implements TestBean {
@Publisher(payload="#return")
@Publisher
@Payload("#return")
public String test(@Header("foo") String foo) {
return "hello";
}