INT-4151: MessageSource Advice Improvement

JIRA: https://jira.spring.io/browse/INT-4151

If the `MessageSource` is already a proxy, we only advise the `receive()` method.
If it's not, we advise all methods, which is incorrect.

* Use `NameMatchMethodPointcutAdvisor` in all advising cases
* Prove with the test case that only `receive()` method is advised for the `MessageSource` proxy
This commit is contained in:
Gary Russell
2016-10-31 13:33:48 -04:00
committed by Artem Bilan
parent 0488b1e2ec
commit dfa061f1cc
4 changed files with 47 additions and 7 deletions

View File

@@ -34,8 +34,7 @@ public abstract class AbstractMessageSourceAdvice implements MethodInterceptor {
@Override
public final Object invoke(MethodInvocation invocation) throws Throwable {
Object target = invocation.getThis();
if (!(target instanceof MessageSource)
|| !invocation.getMethod().getName().equals("receive")) {
if (!(target instanceof MessageSource)) {
return invocation.proceed();
}

View File

@@ -134,15 +134,13 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
if (AopUtils.isAopProxy(this.source)) {
this.appliedAdvices.forEach(((Advised) this.source)::removeAdvice);
for (Advice advice : chain) {
NameMatchMethodPointcutAdvisor sourceAdvisor = new NameMatchMethodPointcutAdvisor(advice);
sourceAdvisor.addMethodName("receive");
((Advised) this.source).addAdvisor(sourceAdvisor);
((Advised) this.source).addAdvisor(adviceToReceiveAdvisor(advice));
}
}
else {
ProxyFactory proxyFactory = new ProxyFactory(this.source);
for (Advice advice : chain) {
proxyFactory.addAdvice(advice);
proxyFactory.addAdvisor(adviceToReceiveAdvisor(advice));
}
this.source = (MessageSource<?>) proxyFactory.getProxy(getBeanClassLoader());
}
@@ -150,6 +148,12 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
this.appliedAdvices.addAll(chain);
}
private NameMatchMethodPointcutAdvisor adviceToReceiveAdvisor(Advice advice) {
NameMatchMethodPointcutAdvisor sourceAdvisor = new NameMatchMethodPointcutAdvisor(advice);
sourceAdvisor.addMethodName("receive");
return sourceAdvisor;
}
@Override
protected void doStart() {
if (this.source instanceof Lifecycle) {

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.endpoint;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -344,10 +345,21 @@ public class PollerAdviceTests {
assertTrue(source.latch.await(10, TimeUnit.SECONDS));
assertNotNull(TestUtils.getPropertyValue(adapter, "trigger.override"));
adapter.stop();
OtherAdvice sourceAdvice = ctx.getBean(OtherAdvice.class);
int count = sourceAdvice.calls;
assertThat(count, greaterThan(0));
((Foo) adapter.getMessageSource()).otherMethod();
assertEquals(count, sourceAdvice.calls);
ctx.close();
}
public static class Source implements MessageSource<Object> {
public interface Foo {
void otherMethod();
}
public static class Source implements MessageSource<Object>, Foo {
private final CountDownLatch latch = new CountDownLatch(5);
@@ -357,6 +369,28 @@ public class PollerAdviceTests {
return null;
}
@Override
public void otherMethod() {
}
}
public static class OtherAdvice extends AbstractMessageSourceAdvice {
private int calls;
@Override
public boolean beforeReceive(MessageSource<?> source) {
this.calls++;
return true;
}
@Override
public Message<?> afterReceive(Message<?> result, MessageSource<?> source) {
return result;
}
}
@Configuration

View File

@@ -13,6 +13,7 @@
<constructor-arg ref="compoundTrigger"/>
<constructor-arg ref="secondary"/>
</bean>
<ref bean="otherAdvice" />
</int:advice-chain>
</int:poller>
</int:inbound-channel-adapter>
@@ -29,4 +30,6 @@
<constructor-arg value="10" />
</bean>
<bean id="otherAdvice" class = "org.springframework.integration.endpoint.PollerAdviceTests.OtherAdvice" />
</beans>