Improve ControlFlowPointcut extensibility

This commit makes ControlFlowPointcut more open to subclasses by:

1. Making the ControlFlowPointcut#clazz field protected.
2. Making the ControlFlowPointcut#methodName field protected.
3. Introducing a protected incrementEvaluationCount() method.

Closes gh-27187
This commit is contained in:
Sam Brannen
2023-10-25 14:53:07 +02:00
parent c0f79ca3bf
commit 5c1cdcb245
2 changed files with 74 additions and 3 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.aop.support;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import org.springframework.aop.Pointcut;
@@ -31,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Rod Johnson
* @author Chris Beams
* @author Sam Brannen
*/
class ControlFlowPointcutTests {
@@ -60,6 +63,57 @@ class ControlFlowPointcutTests {
assertThat(cflow.getEvaluations()).isEqualTo(3);
}
@Test
void controlFlowPointcutIsExtensible() {
@SuppressWarnings("serial")
class CustomControlFlowPointcut extends ControlFlowPointcut {
CustomControlFlowPointcut(Class<?> clazz, String methodName) {
super(clazz, methodName);
}
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
super.incrementEvaluationCount();
return super.matches(method, targetClass, args);
}
Class<?> trackedClass() {
return super.clazz;
}
String trackedMethod() {
return super.methodName;
}
}
CustomControlFlowPointcut cflow = new CustomControlFlowPointcut(One.class, "getAge");
assertThat(cflow.trackedClass()).isEqualTo(One.class);
assertThat(cflow.trackedMethod()).isEqualTo("getAge");
TestBean target = new TestBean("Jane", 27);
ProxyFactory pf = new ProxyFactory(target);
NopInterceptor nop = new NopInterceptor();
pf.addAdvisor(new DefaultPointcutAdvisor(cflow, nop));
ITestBean proxy = (ITestBean) pf.getProxy();
// Not advised: the proxy is not invoked under One#getAge
assertThat(proxy.getAge()).isEqualTo(target.getAge());
assertThat(nop.getCount()).isEqualTo(0);
assertThat(cflow.getEvaluations()).isEqualTo(2); // intentional double increment
// Will be advised: the proxy is invoked under One#getAge
assertThat(new One().getAge(proxy)).isEqualTo(target.getAge());
assertThat(nop.getCount()).isEqualTo(1);
assertThat(cflow.getEvaluations()).isEqualTo(4); // intentional double increment
// Won't be advised: the proxy is not invoked under One#getAge
assertThat(new One().nomatch(proxy)).isEqualTo(target.getAge());
assertThat(nop.getCount()).isEqualTo(1);
assertThat(cflow.getEvaluations()).isEqualTo(6); // intentional double increment
}
/**
* Check that we can use a cflow pointcut only in conjunction with
* a static pointcut: e.g. all setter methods that are invoked under