diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherAnnotationBeanPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherAnnotationBeanPostProcessor.java
index acc6cf3287..f7df98d90c 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherAnnotationBeanPostProcessor.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherAnnotationBeanPostProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -16,26 +16,19 @@
package org.springframework.integration.aop;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.springframework.aop.framework.Advised;
-import org.springframework.aop.framework.ProxyConfig;
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.aop.framework.autoproxy.AbstractBeanFactoryAwareAdvisingPostProcessor;
+import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.core.Ordered;
-import org.springframework.util.ClassUtils;
+import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
/**
* Post-processes beans that contain the
* method-level @{@link org.springframework.integration.annotation.Publisher} annotation.
+ *
+ * Only one bean instance of this processor can be declared in the application context, manual
+ * or automatic by thr framework via annotation or XML processing.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
@@ -46,21 +39,14 @@ import org.springframework.util.ClassUtils;
* @since 2.0
*/
@SuppressWarnings("serial")
-public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
- implements BeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, Ordered {
+public class PublisherAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor
+ implements BeanNameAware, InitializingBean {
- private volatile String defaultChannelName;
+ private String defaultChannelName;
- private volatile PublisherAnnotationAdvisor advisor;
+ private String name;
- private volatile int order = Ordered.LOWEST_PRECEDENCE;
-
- private volatile BeanFactory beanFactory;
-
- private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
- private final Set> nonApplicableCache =
- Collections.newSetFromMap(new ConcurrentHashMap, Boolean>(256));
+ private BeanFactory beanFactory;
/**
* Set the default channel where Messages should be sent if the annotation
@@ -72,64 +58,32 @@ public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
this.defaultChannelName = defaultChannelName;
}
+ @Override
+ public void setBeanName(String name) {
+ this.name = name;
+ }
+
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
+ super.setBeanFactory(beanFactory);
+ PublisherAnnotationAdvisor publisherAnnotationAdvisor = new PublisherAnnotationAdvisor();
+ publisherAnnotationAdvisor.setBeanFactory(beanFactory);
+ publisherAnnotationAdvisor.setDefaultChannelName(this.defaultChannelName);
+ this.advisor = publisherAnnotationAdvisor;
}
@Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- public void setOrder(int order) {
- this.order = order;
- }
-
- @Override
- public int getOrder() {
- return this.order;
- }
-
- @Override
- public void afterPropertiesSet() {
- this.advisor = new PublisherAnnotationAdvisor();
- this.advisor.setBeanFactory(this.beanFactory);
- this.advisor.setDefaultChannelName(this.defaultChannelName);
- }
-
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- Class> targetClass = AopUtils.getTargetClass(bean);
-
- // the set will hold records of prior class scans and will contain the bean classes that can not
- // be assigned to the Advisor interface and therefore can be short circuited
- if (this.nonApplicableCache.contains(targetClass)) {
- return bean;
+ public void afterPropertiesSet() throws Exception {
+ try {
+ this.beanFactory.getBean(PublisherAnnotationBeanPostProcessor.class);
}
-
- if (AopUtils.canApply(this.advisor, targetClass)) {
- if (bean instanceof Advised) {
- ((Advised) bean).addAdvisor(this.advisor);
- return bean;
- }
- else {
- ProxyFactory proxyFactory = new ProxyFactory(bean);
- // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
- proxyFactory.copyFrom(this);
- proxyFactory.addAdvisor(this.advisor);
- return proxyFactory.getProxy(this.beanClassLoader);
- }
- }
- else {
- // cannot apply advisor
- this.nonApplicableCache.add(targetClass);
- return bean;
+ catch (NoUniqueBeanDefinitionException ex) {
+ throw new BeanCreationNotAllowedException(this.name,
+ "Only one 'PublisherAnnotationBeanPostProcessor' bean can be defined in the application context." +
+ " Do not use '@EnablePublisher' (or '') if you declare a" +
+ " 'PublisherAnnotationBeanPostProcessor' bean definition manually. " +
+ "Bean names found: " + ex.getBeanNamesFound());
}
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/EnablePublisher.java b/spring-integration-core/src/main/java/org/springframework/integration/config/EnablePublisher.java
index f949d0fc70..2ab7f6b398 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/EnablePublisher.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/EnablePublisher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2018 the original author or authors.
+ * Copyright 2014-2019 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.
@@ -23,11 +23,15 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.AliasFor;
/**
- * Provides the registration for the {@link org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor}
+ * Provides the registration for the
+ * {@link org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor}
* to allow the use of the {@link org.springframework.integration.annotation.Publisher} annotation.
- * In addition the {@code default-publisher-channel} name can be configured as the {@code value} of this annotation.
+ * In addition the {@code default-publisher-channel} name can be configured as
+ * the {@link #defaultChannel()} of this annotation.
*
* @author Artem Bilan
*
@@ -40,7 +44,39 @@ import org.springframework.context.annotation.Import;
public @interface EnablePublisher {
/**
- * @return the {@code default-publisher-channel} name.
+ * Alias for the {@link #defaultChannel()} attribute.
+ * The {@code default-publisher-channel} name.
+ * @return the channel bean name.
*/
+ @AliasFor("defaultChannel")
String value() default "";
+
+ /**
+ * The {@code default-publisher-channel} name.
+ * @return the channel bean name.
+ * @since 5.1.3
+ */
+ @AliasFor("value")
+ String defaultChannel() default "";
+
+ /**
+ * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
+ * to standard Java interface-based proxies.
+ * @return whether proxy target class or not.
+ * @since 5.1.3
+ */
+ boolean proxyTargetClass() default false;
+
+ /**
+ * Indicate the order in which the
+ * {@link org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor}
+ * should be applied.
+ * The default is {@link Ordered#LOWEST_PRECEDENCE} in order to run
+ * after all other post-processors, so that it can add an advisor to
+ * existing proxies rather than double-proxy.
+ * @return the order for the bean post-processor.
+ * @since 5.1.3
+ */
+ int order() default Ordered.LOWEST_PRECEDENCE;
+
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/PublisherRegistrar.java b/spring-integration-core/src/main/java/org/springframework/integration/config/PublisherRegistrar.java
index eef7885560..1c53abcced 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/PublisherRegistrar.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/PublisherRegistrar.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2019 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.
@@ -37,6 +37,7 @@ import org.springframework.util.StringUtils;
/**
* @author Artem Bilan
* @author Gary Russell
+ *
* @since 4.0
*/
public class PublisherRegistrar implements ImportBeanDefinitionRegistrar {
@@ -48,21 +49,28 @@ public class PublisherRegistrar implements ImportBeanDefinitionRegistrar {
Map annotationAttributes =
importingClassMetadata.getAnnotationAttributes(EnablePublisher.class.getName());
- String value = (annotationAttributes == null
- ? (String) AnnotationUtils.getDefaultValue(EnablePublisher.class)
- : (String) annotationAttributes.get("value"));
+ String defaultChannel =
+ annotationAttributes == null
+ ? (String) AnnotationUtils.getDefaultValue(EnablePublisher.class)
+ : (String) annotationAttributes.get("defaultChannel");
if (!registry.containsBeanDefinition(IntegrationContextUtils.PUBLISHER_ANNOTATION_POSTPROCESSOR_NAME)) {
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(PublisherAnnotationBeanPostProcessor.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- if (StringUtils.hasText(value)) {
- builder.addPropertyValue("defaultChannelName", value);
+ if (StringUtils.hasText(defaultChannel)) {
+ builder.addPropertyValue("defaultChannelName", defaultChannel);
if (logger.isInfoEnabled()) {
- logger.info("Setting '@Publisher' default-output-channel to '" + value + "'.");
+ logger.info("Setting '@Publisher' default-output-channel to '" + defaultChannel + "'.");
}
}
+ if (annotationAttributes != null) {
+ Object proxyTargetClass = annotationAttributes.get("proxyTargetClass");
+ builder.addPropertyValue("proxyTargetClass", proxyTargetClass);
+ Object order = annotationAttributes.get("order");
+ builder.addPropertyValue("order", order);
+ }
registry.registerBeanDefinition(IntegrationContextUtils.PUBLISHER_ANNOTATION_POSTPROCESSOR_NAME,
builder.getBeanDefinition());
}
@@ -71,17 +79,17 @@ public class PublisherRegistrar implements ImportBeanDefinitionRegistrar {
registry.getBeanDefinition(IntegrationContextUtils.PUBLISHER_ANNOTATION_POSTPROCESSOR_NAME);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
PropertyValue defaultChannelPropertyValue = propertyValues.getPropertyValue("defaultChannelName");
- if (StringUtils.hasText(value)) {
+ if (StringUtils.hasText(defaultChannel)) {
if (defaultChannelPropertyValue == null) {
- propertyValues.addPropertyValue("defaultChannelName", value);
+ propertyValues.addPropertyValue("defaultChannelName", defaultChannel);
if (logger.isInfoEnabled()) {
- logger.info("Setting '@Publisher' default-output-channel to '" + value + "'.");
+ logger.info("Setting '@Publisher' default-output-channel to '" + defaultChannel + "'.");
}
}
- else if (!value.equals(defaultChannelPropertyValue.getValue())) {
+ else if (!defaultChannel.equals(defaultChannelPropertyValue.getValue())) {
throw new BeanDefinitionStoreException("When more than one enable publisher definition " +
- "(@EnablePublisher or )" +
- " is found in the context, they all must have the same 'default-publisher-channel' value.");
+ "(@EnablePublisher or ) is found in the context, " +
+ "they all must have the same 'default-publisher-channel' attribute value.");
}
}
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AnnotationConfigParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AnnotationConfigParser.java
index 2887a2b989..7d0c0aa7de 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AnnotationConfigParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AnnotationConfigParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -16,7 +16,7 @@
package org.springframework.integration.config.xml;
-import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Element;
@@ -40,8 +40,6 @@ public class AnnotationConfigParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(final Element element, ParserContext parserContext) {
- IntegrationRegistrar integrationRegistrar = new IntegrationRegistrar();
-
StandardAnnotationMetadata importingClassMetadata =
new StandardAnnotationMetadata(Object.class) {
@@ -51,8 +49,13 @@ public class AnnotationConfigParser implements BeanDefinitionParser {
Element enablePublisherElement =
DomUtils.getChildElementByTagName(element, "enable-publisher");
if (enablePublisherElement != null) {
- return Collections.singletonMap("value",
+ Map attributes = new HashMap<>();
+ attributes.put("defaultChannel",
enablePublisherElement.getAttribute("default-publisher-channel"));
+ attributes.put("proxyTargetClass",
+ enablePublisherElement.getAttribute("proxy-target-class"));
+ attributes.put("order", enablePublisherElement.getAttribute("order"));
+ return attributes;
}
else {
return null;
@@ -65,7 +68,7 @@ public class AnnotationConfigParser implements BeanDefinitionParser {
};
- integrationRegistrar.registerBeanDefinitions(importingClassMetadata, parserContext.getRegistry());
+ new IntegrationRegistrar().registerBeanDefinitions(importingClassMetadata, parserContext.getRegistry());
return null;
}
diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration-5.1.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration-5.1.xsd
index 076793afe4..70935e8728 100644
--- a/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration-5.1.xsd
+++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration-5.1.xsd
@@ -35,6 +35,30 @@
+
+
+
+ Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
+ to standard Java interface-based proxies.
+
+
+
+
+
+
+
+
+
+ Indicate the order in which the
+ 'org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor'
+ should be applied.
+ Defaults to 'org.springframework.core.Ordered.LOWEST_PRECEDENCE'.
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests-context.xml
index 00bde4e2ec..f0b90804bc 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests-context.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java
index efb28cf7ca..1e2df03cf0 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2018 the original author or authors.
+ * Copyright 2014-2019 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.
@@ -19,6 +19,7 @@ package org.springframework.integration.configuration;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.sameInstance;
@@ -51,8 +52,6 @@ import java.util.concurrent.atomic.AtomicReference;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.apache.commons.logging.Log;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -92,6 +91,7 @@ import org.springframework.integration.annotation.Role;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.annotation.UseSpelInvoker;
+import org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.NullChannel;
@@ -127,7 +127,6 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHandler;
-import org.springframework.messaging.MessagingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.ChannelInterceptor;
@@ -295,6 +294,9 @@ public class EnableIntegrationTests {
@Qualifier("enableIntegrationTests.ChildConfiguration.autoCreatedChannelMessageSource.inboundChannelAdapter")
private Lifecycle autoCreatedChannelMessageSourceAdapter;
+ @Autowired
+ private PublisherAnnotationBeanPostProcessor publisherAnnotationBeanPostProcessor;
+
@Test
public void testAnnotatedServiceActivator() throws Exception {
this.serviceActivatorEndpoint.start();
@@ -666,7 +668,7 @@ public class EnableIntegrationTests {
List integers = ref.get();
assertEquals(5, integers.size());
- assertThat(integers, Matchers.contains(2, 4, 6, 8, 10));
+ assertThat(integers, contains(2, 4, 6, 8, 10));
}
@Test
@@ -744,13 +746,17 @@ public class EnableIntegrationTests {
assertNotNull(receive);
assertEquals(testDate, receive.getPayload());
+
+ assertTrue(this.publisherAnnotationBeanPostProcessor.isProxyTargetClass());
+ assertEquals(Integer.MAX_VALUE - 1, this.publisherAnnotationBeanPostProcessor.getOrder());
}
@Configuration
@ComponentScan
@IntegrationComponentScan
@EnableIntegration
-// INT-3853 @PropertySource("classpath:org/springframework/integration/configuration/EnableIntegrationTests.properties")
+ // INT-3853
+ // @PropertySource("classpath:org/springframework/integration/configuration/EnableIntegrationTests.properties")
@EnableMessageHistory({ "input", "publishedChannel", "annotationTestService*" })
public static class ContextConfiguration {
@@ -996,7 +1002,7 @@ public class EnableIntegrationTests {
@EnableIntegration
@ImportResource("classpath:org/springframework/integration/configuration/EnableIntegrationTests-context.xml")
@EnableMessageHistory("${message.history.tracked.components}")
- @EnablePublisher("publishedChannel")
+ @EnablePublisher(defaultChannel = "publishedChannel")
@EnableAsync
public static class ContextConfiguration2 {
@@ -1026,14 +1032,9 @@ public class EnableIntegrationTests {
@ServiceActivator(inputChannel = "sendAsyncChannel")
@Role("foo")
public MessageHandler sendAsyncHandler() {
- return new MessageHandler() {
-
- @Override
- public void handleMessage(Message> message) throws MessagingException {
- asyncAnnotationProcessThread().set(Thread.currentThread());
- asyncAnnotationProcessLatch().countDown();
- }
-
+ return message -> {
+ asyncAnnotationProcessThread().set(Thread.currentThread());
+ asyncAnnotationProcessLatch().countDown();
};
}
@@ -1139,7 +1140,7 @@ public class EnableIntegrationTests {
@Bean
public AnnotationTestService annotationTestService() {
- return new AnnotationTestServiceImpl();
+ return new AnnotationTestService();
}
@Bean
@@ -1155,7 +1156,8 @@ public class EnableIntegrationTests {
@Bean
@ServiceActivator(inputChannel = "myHandlerChannel", adviceChain = "myHandlerAdvice")
public MessageHandler myHandler() {
- return message -> { };
+ return message -> {
+ };
}
@Bean
@@ -1198,53 +1200,12 @@ public class EnableIntegrationTests {
}
- public interface AnnotationTestService {
-
- String handle(String payload);
-
- String handle1(String payload);
-
- String handle2(String payload);
-
- String handle3(String payload);
-
- String handle4(String payload);
-
- String transform(Message message);
-
- String transform2(Message message);
-
- Integer count();
-
- String foo();
-
- Message> message();
-
- Integer annCount();
-
- Integer annCount1();
-
- Integer annCount2();
-
- Integer annCount5();
-
- Integer annCount8();
-
- Integer annAgg1(List> messages);
-
- Integer annAgg2(List> messages);
-
- Integer multiply(Integer value);
-
- }
-
- public static class AnnotationTestServiceImpl implements Lifecycle, AnnotationTestService {
+ public static class AnnotationTestService implements Lifecycle {
private final AtomicInteger counter = new AtomicInteger();
private boolean running;
- @Override
@ServiceActivator(inputChannel = "input", outputChannel = "output", autoStartup = "false",
poller = @Poller(maxMessagesPerPoll = "${poller.maxMessagesPerPoll}",
fixedDelay = "${poller.interval}",
@@ -1256,7 +1217,6 @@ public class EnableIntegrationTests {
return payload.toUpperCase();
}
- @Override
@ServiceActivator(inputChannel = "input1", outputChannel = "output",
poller = @Poller(maxMessagesPerPoll = "${poller.maxMessagesPerPoll}",
fixedRate = "${poller.interval}"))
@@ -1266,7 +1226,6 @@ public class EnableIntegrationTests {
return payload.toUpperCase();
}
- @Override
@ServiceActivator(inputChannel = "input2", outputChannel = "output",
poller = @Poller(maxMessagesPerPoll = "${poller.maxMessagesPerPoll}", cron = "0 5 7 * * *"))
@Publisher
@@ -1275,7 +1234,6 @@ public class EnableIntegrationTests {
return payload.toUpperCase();
}
- @Override
@ServiceActivator(inputChannel = "input3", outputChannel = "output", poller = @Poller("myPoller"))
@Publisher
@Payload("#args[0].toLowerCase()")
@@ -1283,7 +1241,6 @@ public class EnableIntegrationTests {
return payload.toUpperCase();
}
- @Override
@ServiceActivator(inputChannel = "input4", outputChannel = "output",
poller = @Poller(trigger = "myTrigger"))
@Publisher
@@ -1303,7 +1260,6 @@ public class EnableIntegrationTests {
return payload.toUpperCase();
}*/
- @Override
@Transformer(inputChannel = "gatewayChannel")
public String transform(Message message) {
assertTrue(message.getHeaders().containsKey("foo"));
@@ -1313,7 +1269,6 @@ public class EnableIntegrationTests {
return this.handle(message.getPayload()) + Arrays.asList(new Throwable().getStackTrace()).toString();
}
- @Override
@Transformer(inputChannel = "gatewayChannel2")
@UseSpelInvoker(compilerMode = "${xxxxxxxx:IMMEDIATE}")
public String transform2(Message message) {
@@ -1324,20 +1279,17 @@ public class EnableIntegrationTests {
return this.handle(message.getPayload()) + "2" + Arrays.asList(new Throwable().getStackTrace()).toString();
}
- @Override
@MyInboundChannelAdapter1
public Integer count() {
return this.counter.incrementAndGet();
}
- @Override
@InboundChannelAdapter(value = "fooChannel",
poller = @Poller(trigger = "onlyOnceTrigger", maxMessagesPerPoll = "2"))
public String foo() {
return "foo";
}
- @Override
@InboundChannelAdapter(value = "messageChannel", poller = @Poller(fixedDelay = "${poller.interval}",
maxMessagesPerPoll = "1"))
public Message> message() {
@@ -1361,44 +1313,37 @@ public class EnableIntegrationTests {
// metaAnnotation tests
- @Override
@MyServiceActivator
public Integer annCount() {
return 0;
}
- @Override
@MyServiceActivator1(inputChannel = "annInput1", autoStartup = "true",
adviceChain = { "annAdvice1" }, poller = @Poller(fixedRate = "2000"))
public Integer annCount1() {
return 0;
}
- @Override
@MyServiceActivatorNoLocalAtts
public Integer annCount2() {
return 0;
}
- @Override
@MyServiceActivator5
public Integer annCount5() {
return 0;
}
- @Override
@MyServiceActivator8
public Integer annCount8() {
return 0;
}
- @Override
@MyAggregator
public Integer annAgg1(List> messages) {
return 42;
}
- @Override
@MyAggregatorDefaultOverrideDefaults
public Integer annAgg2(List> messages) {
return 42;
@@ -1408,7 +1353,6 @@ public class EnableIntegrationTests {
/*@BridgeFrom("")
public void invalidBridgeAnnotationMethod(Object payload) {}*/
- @Override
@ServiceActivator(inputChannel = "monoChannel")
public Integer multiply(Integer value) {
return value * 2;
@@ -1693,25 +1637,4 @@ public class EnableIntegrationTests {
}
- public class RegexMatcher extends BaseMatcher {
-
- private final String regex;
-
- public RegexMatcher(String regex) {
- this.regex = regex;
- }
-
- @Override
- public boolean matches(Object o) {
- return ((String) o).matches(regex);
-
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("matches regex=");
- }
-
- }
-
}
diff --git a/src/reference/asciidoc/message-publishing.adoc b/src/reference/asciidoc/message-publishing.adoc
index d88de47846..47fab0c4cf 100644
--- a/src/reference/asciidoc/message-publishing.adoc
+++ b/src/reference/asciidoc/message-publishing.adoc
@@ -142,6 +142,8 @@ public class IntegrationConfiguration {
----
====
+Starting with version 5.1.3, the `` component, as well as the `@EnablePublisher` annotation have the `proxy-target-class` and `order` attributes for tuning the `ProxyFactory` configuration.
+
Similar to other Spring annotations (`@Component`, `@Scheduled`, and so on), you can also use `@Publisher` as a meta-annotation.
This means that you can define your own annotations that are treated in the same way as the `@Publisher` itself.
The following example shows how to do so:
@@ -321,7 +323,7 @@ Another way of handling this type of scenario is with a wire-tap. See <` XML element.
diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc
index 0796e57151..3cb83cb55a 100644
--- a/src/reference/asciidoc/whats-new.adoc
+++ b/src/reference/asciidoc/whats-new.adoc
@@ -119,6 +119,7 @@ See <> for more information.
==== @Publisher annotation changes
Starting with version 5.1, you must explicitly turn on the `@Publisher` AOP functionality by using `@EnablePublisher` or by using the `` child element on ``.
+Also the `proxy-target-class` and `order` attributes have been added for tuning the `ProxyFactory` configuration.
See <> for more information.