Skip to content

Commit

Permalink
[WIP] Ensure ClassFilter and MethodMatcher implementations are cacheable
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrannen committed Sep 18, 2019
1 parent b2aad1c commit db4f386
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
Expand All @@ -23,6 +23,11 @@
* <p>Can be used as part of a {@link Pointcut} or for the entire
* targeting of an {@link IntroductionAdvisor}.
*
* <p>Concrete implementations of this interface should provide proper
* implementations of {@link Object#equals(Object)} and {@link Object#hashCode()}
* in order to allow the filter to be used in caching scenarios &mdash; for
* example, in proxies generated by CGLIB.
*
* @author Rod Johnson
* @see Pointcut
* @see MethodMatcher
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
Expand All @@ -22,13 +22,15 @@
import org.springframework.aop.ClassFilter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
* Spring AOP {@link ClassFilter} implementation using AspectJ type matching.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 2.0
*/
public class TypePatternClassFilter implements ClassFilter {
Expand Down Expand Up @@ -113,4 +115,21 @@ private String replaceBooleanOperators(String pcExpr) {
result = StringUtils.replace(result, " or ", " || ");
return StringUtils.replace(result, " not ", " ! ");
}

@Override
public boolean equals(Object other) {
return (this == other || (other instanceof TypePatternClassFilter &&
ObjectUtils.nullSafeEquals(this.typePattern, ((TypePatternClassFilter) other).typePattern)));
}

@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.typePattern);
}

@Override
public String toString() {
return getClass().getName() + ": " + this.typePattern;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 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.
Expand All @@ -17,6 +17,7 @@
package org.springframework.aop.support;

import java.io.Serializable;
import java.util.Arrays;

import org.springframework.aop.ClassFilter;
import org.springframework.util.Assert;
Expand All @@ -28,6 +29,7 @@
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @author Sam Brannen
* @since 11.11.2003
* @see MethodMatchers
* @see Pointcuts
Expand Down Expand Up @@ -89,9 +91,9 @@ public static ClassFilter intersection(ClassFilter[] classFilters) {
@SuppressWarnings("serial")
private static class UnionClassFilter implements ClassFilter, Serializable {

private ClassFilter[] filters;
private final ClassFilter[] filters;

public UnionClassFilter(ClassFilter[] filters) {
UnionClassFilter(ClassFilter[] filters) {
this.filters = filters;
}

Expand All @@ -115,6 +117,12 @@ public boolean equals(Object other) {
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.filters);
}

@Override
public String toString() {
return getClass().getName() + ": " + Arrays.toString(this.filters);
}

}


Expand All @@ -124,9 +132,9 @@ public int hashCode() {
@SuppressWarnings("serial")
private static class IntersectionClassFilter implements ClassFilter, Serializable {

private ClassFilter[] filters;
private final ClassFilter[] filters;

public IntersectionClassFilter(ClassFilter[] filters) {
IntersectionClassFilter(ClassFilter[] filters) {
this.filters = filters;
}

Expand All @@ -150,6 +158,12 @@ public boolean equals(Object other) {
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.filters);
}

@Override
public String toString() {
return getClass().getName() + ": " + Arrays.toString(this.filters);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @author Sam Brannen
*/
@SuppressWarnings("serial")
public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher, Serializable {

private Class<?> clazz;
private final Class<?> clazz;

@Nullable
private String methodName;
private final String methodName;

private volatile int evaluations;

Expand Down Expand Up @@ -142,4 +143,9 @@ public int hashCode() {
return code;
}

@Override
public String toString() {
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName;
}

}
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -168,7 +168,7 @@ public int hashCode() {

@Override
public String toString() {
return ClassUtils.getShortName(getClass()) + ": advice [" + this.advice + "]; interfaces " +
return getClass().getName() + ": advice [" + this.advice + "]; interfaces " +
ClassUtils.classNamesToString(this.interfaces);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -19,19 +19,22 @@
import java.io.Serializable;

import org.springframework.aop.ClassFilter;
import org.springframework.util.Assert;

/**
* Simple ClassFilter implementation that passes classes (and optionally subclasses).
*
* @author Rod Johnson
* @author Sam Brannen
*/
@SuppressWarnings("serial")
public class RootClassFilter implements ClassFilter, Serializable {

private Class<?> clazz;
private final Class<?> clazz;


public RootClassFilter(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
this.clazz = clazz;
}

Expand All @@ -41,4 +44,20 @@ public boolean matches(Class<?> candidate) {
return this.clazz.isAssignableFrom(candidate);
}

@Override
public boolean equals(Object other) {
return (this == other || (other instanceof RootClassFilter &&
this.clazz.equals(((RootClassFilter) other).clazz)));
}

@Override
public int hashCode() {
return this.clazz.hashCode();
}

@Override
public String toString() {
return getClass().getName() + ": " + this.clazz.getName();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
Expand Down Expand Up @@ -62,7 +62,7 @@ public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationTyp
}

/**
* Create a new AnnotationMatchingPointcut for the given annotation type.
* Create a new AnnotationMatchingPointcut for the given annotation types.
* @param classAnnotationType the annotation type to look for at the class level
* (can be {@code null})
* @param methodAnnotationType the annotation type to look for at the method level
Expand All @@ -75,7 +75,7 @@ public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnn
}

/**
* Create a new AnnotationMatchingPointcut for the given annotation type.
* Create a new AnnotationMatchingPointcut for the given annotation types.
* @param classAnnotationType the annotation type to look for at the class level
* (can be {@code null})
* @param methodAnnotationType the annotation type to look for at the method level
Expand Down Expand Up @@ -138,7 +138,7 @@ public int hashCode() {

@Override
public String toString() {
return "AnnotationMatchingPointcut: " + this.classFilter + ", " +this.methodMatcher;
return "AnnotationMatchingPointcut: " + this.classFilter + ", " + this.methodMatcher;
}


Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -31,6 +31,7 @@
* interface, if any, and the corresponding method on the target class).
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 2.0
* @see AnnotationMatchingPointcut
*/
Expand Down Expand Up @@ -94,7 +95,7 @@ public boolean equals(Object other) {
return false;
}
AnnotationMethodMatcher otherMm = (AnnotationMethodMatcher) other;
return this.annotationType.equals(otherMm.annotationType);
return (this.annotationType.equals(otherMm.annotationType) && this.checkInherited == otherMm.checkInherited);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 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.
Expand Down Expand Up @@ -34,6 +34,7 @@
* @author Rod Johnson
* @author Rick Evans
* @author Chris Beams
* @author Sam Brannen
*/
public class TypePatternClassFilterTests {

Expand Down Expand Up @@ -88,4 +89,34 @@ public void testInvocationOfMatchesMethodBlowsUpWhenNoTypePatternHasBeenSet() th
new TypePatternClassFilter().matches(String.class);
}

@Test
public void testEquals() {
TypePatternClassFilter filter1 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter2 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter3 = new TypePatternClassFilter("org.springframework.tests.*");

assertEquals(filter1, filter2);
assertNotEquals(filter1, filter3);
}

@Test
public void testHashCode() {
TypePatternClassFilter filter1 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter2 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter3 = new TypePatternClassFilter("org.springframework.tests.*");

assertEquals(filter1.hashCode(), filter2.hashCode());
assertNotEquals(filter1.hashCode(), filter3.hashCode());
}

@Test
public void testToString() {
TypePatternClassFilter filter1 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter2 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");

assertEquals("org.springframework.aop.aspectj.TypePatternClassFilter: org.springframework.tests.sample.beans.*",
filter1.toString());
assertEquals(filter1.toString(), filter2.toString());
}

}
Loading

0 comments on commit db4f386

Please sign in to comment.