提交 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;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.Assert;
......@@ -50,6 +51,8 @@ public abstract class AnnotationUtils {
/** The attribute name for annotations with a single element */
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}.
......@@ -120,26 +123,45 @@ public abstract class AnnotationUtils {
private static <A extends Annotation> A searchOnInterfaces(Method method, Class<A> annotationType, Class[] ifcs) {
A annotation = null;
for (Class<?> iface : ifcs) {
Method equivalentMethod;
try {
equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
annotation = getAnnotation(equivalentMethod, annotationType);
if (isInterfaceWithAnnotatedMethods(iface)) {
try {
Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
annotation = getAnnotation(equivalentMethod, annotationType);
}
catch (NoSuchMethodException ex) {
// Skip this interface - it doesn't have the method...
}
if (annotation != null) {
break;
}
}
catch (NoSuchMethodException e) {
// skip this interface - it doesn't have the method
}
return annotation;
}
private static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
synchronized (annotatedInterfaceCache) {
Boolean flag = annotatedInterfaceCache.get(iface);
if (flag != null) {
return flag;
}
if (annotation != null) {
break;
boolean found = false;
for (Method ifcMethod : iface.getMethods()) {
if (ifcMethod.getAnnotations().length > 0) {
found = true;
break;
}
}
annotatedInterfaceCache.put(iface, found);
return found;
}
return annotation;
}
/**
* 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
* {@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
* 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
......@@ -171,7 +193,7 @@ public abstract class AnnotationUtils {
}
}
Class<?> superClass = clazz.getSuperclass();
if (superClass == null || superClass.equals(Object.class)) {
if (superClass == null || superClass == Object.class) {
return null;
}
return findAnnotation(superClass, annotationType);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册