提交 3c067e5d 编写于 作者: J Juergen Hoeller

optimized AnnotationUtils findAnnotation performance for repeated search on...

optimized AnnotationUtils findAnnotation performance for repeated search on same interfaces (SPR-7630)
上级 0f924820
...@@ -21,6 +21,7 @@ import java.lang.reflect.Method; ...@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap;
import org.springframework.core.BridgeMethodResolver; import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.Assert; import org.springframework.util.Assert;
...@@ -50,6 +51,8 @@ public abstract class AnnotationUtils { ...@@ -50,6 +51,8 @@ public abstract class AnnotationUtils {
/** The attribute name for annotations with a single element */ /** The attribute name for annotations with a single element */
static final String VALUE = "value"; static final String VALUE = "value";
private static final Map<Class, Boolean> annotatedInterfaceCache = new WeakHashMap<Class, Boolean>();
/** /**
* Get all {@link Annotation Annotations} from the supplied {@link Method}. * Get all {@link Annotation Annotations} from the supplied {@link Method}.
...@@ -120,26 +123,45 @@ public abstract class AnnotationUtils { ...@@ -120,26 +123,45 @@ public abstract class AnnotationUtils {
private static <A extends Annotation> A searchOnInterfaces(Method method, Class<A> annotationType, Class[] ifcs) { private static <A extends Annotation> A searchOnInterfaces(Method method, Class<A> annotationType, Class[] ifcs) {
A annotation = null; A annotation = null;
for (Class<?> iface : ifcs) { for (Class<?> iface : ifcs) {
Method equivalentMethod; if (isInterfaceWithAnnotatedMethods(iface)) {
try { try {
equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes()); Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
annotation = getAnnotation(equivalentMethod, annotationType); annotation = getAnnotation(equivalentMethod, annotationType);
} }
catch (NoSuchMethodException e) { catch (NoSuchMethodException ex) {
// skip this interface - it doesn't have the method // Skip this interface - it doesn't have the method...
} }
if (annotation != null) { if (annotation != null) {
break; break;
} }
} }
}
return annotation; return annotation;
} }
private static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
synchronized (annotatedInterfaceCache) {
Boolean flag = annotatedInterfaceCache.get(iface);
if (flag != null) {
return flag;
}
boolean found = false;
for (Method ifcMethod : iface.getMethods()) {
if (ifcMethod.getAnnotations().length > 0) {
found = true;
break;
}
}
annotatedInterfaceCache.put(iface, found);
return found;
}
}
/** /**
* Find a single {@link Annotation} of <code>annotationType</code> from the supplied {@link Class}, * Find a single {@link Annotation} of <code>annotationType</code> from the supplied {@link Class},
* traversing its interfaces and super classes if no annotation can be found on the given class itself. * traversing its interfaces and superclasses if no annotation can be found on the given class itself.
* <p>This method explicitly handles class-level annotations which are not declared as * <p>This method explicitly handles class-level annotations which are not declared as
* {@link Inherited inherited} <i>as well as annotations on interfaces</i>. * {@link java.lang.annotation.Inherited inherited} <i>as well as annotations on interfaces</i>.
* <p>The algorithm operates as follows: Searches for an annotation on the given class and returns * <p>The algorithm operates as follows: Searches for an annotation on the given class and returns
* it if found. Else searches all interfaces that the given class declares, returning the annotation * it if found. Else searches all interfaces that the given class declares, returning the annotation
* from the first matching candidate, if any. Else proceeds with introspection of the superclass * from the first matching candidate, if any. Else proceeds with introspection of the superclass
...@@ -171,7 +193,7 @@ public abstract class AnnotationUtils { ...@@ -171,7 +193,7 @@ public abstract class AnnotationUtils {
} }
} }
Class<?> superClass = clazz.getSuperclass(); Class<?> superClass = clazz.getSuperclass();
if (superClass == null || superClass.equals(Object.class)) { if (superClass == null || superClass == Object.class) {
return null; return null;
} }
return findAnnotation(superClass, annotationType); return findAnnotation(superClass, annotationType);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册