INT-4427 add value attribute to the @Publisher

JIRA: https://jira.spring.io/browse/INT-4427
This commit is contained in:
jmaxwell
2018-03-07 15:21:15 -06:00
committed by Artem Bilan
parent f479270dcd
commit a92933e800
2 changed files with 158 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 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.
@@ -21,16 +21,16 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Annotation to indicate that a method, or all public methods if applied at
* class-level, should publish Messages.
* Annotation to indicate that a method, or all public methods if applied at class-level,
* should publish Messages.
* <p>
* By default, the Message will be constructed from the return value of the method
* invocation
* and sent to a channel specified by the {@link #channel()} attribute.
* However, a combination of both @Payload and @Header annotations
* can be used to further manage the message structure. See the reference manual for
* examples.
* invocation and sent to a channel specified by the {@link #channel()} attribute.
* However, a combination of both @Payload and @Header annotations can be used to further
* manage the message structure. See the reference manual for examples.
* <p>
* Note: unlike @Gateway, this annotation is used to generate an AOP Advice for an
* existing service and its method implementation. The message sending is a side effect
@@ -40,17 +40,28 @@ import java.lang.annotation.Target;
* The XML equivalent is {@code <int:publishing-interceptor>}
*
* @author Mark Fisher
* @author Jeff Maxwell
*
* @since 2.0
*
* @see org.springframework.integration.aop.MessagePublishingInterceptor
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Publisher {
/**
* Alias for the {@link #channel()} attribute.
* @return The name of the Message Channel to which Messages will be published.
* @since 5.0.4
*/
@AliasFor("channel")
String value() default "";
/**
* @return The name of the Message Channel to which Messages will be published.
*/
@AliasFor("value")
String channel() default "";
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -29,27 +29,27 @@ import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.integration.annotation.Publisher;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.Payload;
/**
* @author Mark Fisher
* @author Jeff Maxwell
*
* @since 2.0
*/
public class PublisherAnnotationAdvisorTests {
private final StaticApplicationContext context = new StaticApplicationContext();
@Before
public void setup() {
context.registerSingleton("testChannel", QueueChannel.class);
context.registerSingleton("testMetaChannel", QueueChannel.class);
}
@Test
public void annotationAtMethodLevelOnVoidReturnWithParamAnnotation() {
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
@@ -120,6 +120,75 @@ public class PublisherAnnotationAdvisorTests {
assertEquals("foo", message.getPayload());
}
@Test
public void annotationViaValueAtMethodLevelOnVoidReturnWithParamAnnotation() {
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
advisor.setBeanFactory(context);
QueueChannel testChannel = context.getBean("testChannel", QueueChannel.class);
ProxyFactory pf = new ProxyFactory(new AnnotationViaValueAtMethodLevelTestBeanImpl());
pf.addAdvisor(advisor);
TestVoidBean proxy = (TestVoidBean) pf.getProxy();
proxy.testVoidMethod("foo");
Message<?> message = testChannel.receive(0);
assertNotNull(message);
assertEquals("foo", message.getPayload());
}
@Test
public void annotationViaValueAtMethodLevel() {
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
advisor.setBeanFactory(context);
QueueChannel testChannel = context.getBean("testChannel", QueueChannel.class);
ProxyFactory pf = new ProxyFactory(new AnnotationViaValueAtMethodLevelTestBeanImpl());
pf.addAdvisor(advisor);
TestBean proxy = (TestBean) pf.getProxy();
proxy.test();
Message<?> message = testChannel.receive(0);
assertNotNull(message);
assertEquals("foo", message.getPayload());
}
@Test
public void annotationViaValueAtClassLevel() {
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
advisor.setBeanFactory(context);
QueueChannel testChannel = context.getBean("testChannel", QueueChannel.class);
ProxyFactory pf = new ProxyFactory(new AnnotationViaValueAtClassLevelTestBeanImpl());
pf.addAdvisor(advisor);
TestBean proxy = (TestBean) pf.getProxy();
proxy.test();
Message<?> message = testChannel.receive(0);
assertNotNull(message);
assertEquals("foo", message.getPayload());
}
@Test
public void metaAnnotationViaValueAtMethodLevel() {
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
advisor.setBeanFactory(context);
QueueChannel testMetaChannel = context.getBean("testMetaChannel", QueueChannel.class);
ProxyFactory pf = new ProxyFactory(new MetaAnnotationViaValueAtMethodLevelTestBeanImpl());
pf.addAdvisor(advisor);
TestBean proxy = (TestBean) pf.getProxy();
proxy.test();
Message<?> message = testMetaChannel.receive(0);
assertNotNull(message);
assertEquals("foo", message.getPayload());
}
@Test
public void metaAnnotationViaValueAtClassLevel() {
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
advisor.setBeanFactory(context);
QueueChannel testMetaChannel = context.getBean("testMetaChannel", QueueChannel.class);
ProxyFactory pf = new ProxyFactory(new MetaAnnotationViaValueAtClassLevelTestBeanImpl());
pf.addAdvisor(advisor);
TestBean proxy = (TestBean) pf.getProxy();
proxy.test();
Message<?> message = testMetaChannel.receive(0);
assertNotNull(message);
assertEquals("foo", message.getPayload());
}
interface TestBean {
@@ -127,58 +196,114 @@ public class PublisherAnnotationAdvisorTests {
}
interface TestVoidBean {
void testVoidMethod(String s);
}
static class AnnotationAtMethodLevelTestBeanImpl implements TestBean, TestVoidBean {
@Override
@Publisher(channel = "testChannel")
public String test() {
return "foo";
}
@Override
@Publisher(channel = "testChannel")
public void testVoidMethod(@Payload String s) { }
}
public void testVoidMethod(@Payload String s) {
}
}
@Publisher(channel = "testChannel")
static class AnnotationAtClassLevelTestBeanImpl implements TestBean {
@Override
public String test() {
return "foo";
}
}
@Target({ElementType.METHOD, ElementType.TYPE})
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Publisher(channel = "testMetaChannel")
public @interface TestMetaPublisher {
}
}
static class MetaAnnotationAtMethodLevelTestBeanImpl implements TestBean {
@Override
@TestMetaPublisher
public String test() {
return "foo";
}
}
}
@TestMetaPublisher
static class MetaAnnotationAtClassLevelTestBeanImpl implements TestBean {
@Override
public String test() {
return "foo";
}
}
static class AnnotationViaValueAtMethodLevelTestBeanImpl implements TestBean, TestVoidBean {
@Override
@Publisher("testChannel")
public String test() {
return "foo";
}
@Override
@Publisher("testChannel")
public void testVoidMethod(@Payload String s) {
}
}
@Publisher("testChannel")
static class AnnotationViaValueAtClassLevelTestBeanImpl implements TestBean {
@Override
public String test() {
return "foo";
}
}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Publisher("testMetaChannel")
public @interface TestMetaPublisherViaValue {
}
static class MetaAnnotationViaValueAtMethodLevelTestBeanImpl implements TestBean {
@Override
@TestMetaPublisherViaValue
public String test() {
return "foo";
}
}
@TestMetaPublisherViaValue
static class MetaAnnotationViaValueAtClassLevelTestBeanImpl implements TestBean {
@Override
public String test() {
return "foo";
}
}
}