Browse Source

Polish ControlFlowPointcut[Tests]

pull/31518/head
Sam Brannen 1 year ago
parent
commit
c0f79ca3bf
  1. 26
      spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java
  2. 30
      spring-aop/src/test/java/org/springframework/aop/support/ControlFlowPointcutTests.java

26
spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java

@ -28,8 +28,9 @@ import org.springframework.util.Assert; @@ -28,8 +28,9 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Pointcut and method matcher for use in simple <b>cflow</b>-style pointcut.
* Note that evaluating such pointcuts is 10-15 times slower than evaluating
* Pointcut and method matcher for use as a simple <b>cflow</b>-style pointcut.
*
* <p>Note that evaluating such pointcuts is 10-15 times slower than evaluating
* normal pointcuts, but they are useful in some cases.
*
* @author Rod Johnson
@ -45,12 +46,12 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -45,12 +46,12 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Nullable
private final String methodName;
private final AtomicInteger evaluations = new AtomicInteger();
private final AtomicInteger evaluationCount = new AtomicInteger();
/**
* Construct a new pointcut that matches all control flows below that class.
* @param clazz the clazz
* Construct a new pointcut that matches all control flows below the given class.
* @param clazz the class
*/
public ControlFlowPointcut(Class<?> clazz) {
this(clazz, null);
@ -58,9 +59,10 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -58,9 +59,10 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
/**
* Construct a new pointcut that matches all calls below the given method
* in the given class. If no method name is given, matches all control flows
* in the given class.
* <p>If no method name is given, the pointcut matches all control flows
* below the given class.
* @param clazz the clazz
* @param clazz the class
* @param methodName the name of the method (may be {@code null})
*/
public ControlFlowPointcut(Class<?> clazz, @Nullable String methodName) {
@ -72,6 +74,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -72,6 +74,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
/**
* Subclasses can override this for greater filtering (and performance).
* <p>The default implementation always returns {@code true}.
*/
@Override
public boolean matches(Class<?> clazz) {
@ -80,6 +83,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -80,6 +83,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
/**
* Subclasses can override this if it's possible to filter out some candidate classes.
* <p>The default implementation always returns {@code true}.
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
@ -93,7 +97,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -93,7 +97,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
this.evaluations.incrementAndGet();
this.evaluationCount.incrementAndGet();
for (StackTraceElement element : new Throwable().getStackTrace()) {
if (element.getClassName().equals(this.clazz.getName()) &&
@ -105,10 +109,12 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -105,10 +109,12 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
}
/**
* It's useful to know how many times we've fired, for optimization.
* Get the number of times {@link #matches(Method, Class, Object...)} has been
* evaluated.
* <p>Useful for optimization and testing purposes.
*/
public int getEvaluations() {
return this.evaluations.get();
return this.evaluationCount.get();
}

30
spring-aop/src/test/java/org/springframework/aop/support/ControlFlowPointcutTests.java

@ -27,13 +27,15 @@ import org.springframework.beans.testfixture.beans.TestBean; @@ -27,13 +27,15 @@ import org.springframework.beans.testfixture.beans.TestBean;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ControlFlowPointcut}.
*
* @author Rod Johnson
* @author Chris Beams
*/
public class ControlFlowPointcutTests {
class ControlFlowPointcutTests {
@Test
public void testMatches() {
void matches() {
TestBean target = new TestBean();
target.setAge(27);
NopInterceptor nop = new NopInterceptor();
@ -45,10 +47,12 @@ public class ControlFlowPointcutTests { @@ -45,10 +47,12 @@ public class ControlFlowPointcutTests {
// Not advised, not under One
assertThat(proxied.getAge()).isEqualTo(target.getAge());
assertThat(nop.getCount()).isEqualTo(0);
assertThat(cflow.getEvaluations()).isEqualTo(1);
// Will be advised
assertThat(new One().getAge(proxied)).isEqualTo(target.getAge());
assertThat(nop.getCount()).isEqualTo(1);
assertThat(cflow.getEvaluations()).isEqualTo(2);
// Won't be advised
assertThat(new One().nomatch(proxied)).isEqualTo(target.getAge());
@ -64,7 +68,7 @@ public class ControlFlowPointcutTests { @@ -64,7 +68,7 @@ public class ControlFlowPointcutTests {
* expensive.
*/
@Test
public void testSelectiveApplication() {
void selectiveApplication() {
TestBean target = new TestBean();
target.setAge(27);
NopInterceptor nop = new NopInterceptor();
@ -91,24 +95,26 @@ public class ControlFlowPointcutTests { @@ -91,24 +95,26 @@ public class ControlFlowPointcutTests {
}
@Test
public void testEqualsAndHashCode() throws Exception {
void equalsAndHashCode() throws Exception {
assertThat(new ControlFlowPointcut(One.class)).isEqualTo(new ControlFlowPointcut(One.class));
assertThat(new ControlFlowPointcut(One.class, "getAge")).isEqualTo(new ControlFlowPointcut(One.class, "getAge"));
assertThat(new ControlFlowPointcut(One.class, "getAge").equals(new ControlFlowPointcut(One.class))).isFalse();
assertThat(new ControlFlowPointcut(One.class).hashCode()).isEqualTo(new ControlFlowPointcut(One.class).hashCode());
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode()).isEqualTo(new ControlFlowPointcut(One.class, "getAge").hashCode());
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode()).isNotEqualTo(new ControlFlowPointcut(One.class).hashCode());
assertThat(new ControlFlowPointcut(One.class, "getAge")).isNotEqualTo(new ControlFlowPointcut(One.class));
assertThat(new ControlFlowPointcut(One.class)).hasSameHashCodeAs(new ControlFlowPointcut(One.class));
assertThat(new ControlFlowPointcut(One.class, "getAge")).hasSameHashCodeAs(new ControlFlowPointcut(One.class, "getAge"));
assertThat(new ControlFlowPointcut(One.class, "getAge")).doesNotHaveSameHashCodeAs(new ControlFlowPointcut(One.class));
}
@Test
public void testToString() {
assertThat(new ControlFlowPointcut(One.class).toString())
void testToString() {
assertThat(new ControlFlowPointcut(One.class)).asString()
.isEqualTo(ControlFlowPointcut.class.getName() + ": class = " + One.class.getName() + "; methodName = null");
assertThat(new ControlFlowPointcut(One.class, "getAge").toString())
assertThat(new ControlFlowPointcut(One.class, "getAge")).asString()
.isEqualTo(ControlFlowPointcut.class.getName() + ": class = " + One.class.getName() + "; methodName = getAge");
}
public class One {
private static class One {
int getAge(ITestBean proxied) {
return proxied.getAge();
}

Loading…
Cancel
Save