diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java index af84f7b5256..b7a528609d7 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -188,41 +188,46 @@ public class AnnotatedElementUtils { Processor processor, Set visited, int metaDepth) { if (visited.add(element)) { - Annotation[] annotations = - (traverseClassHierarchy ? element.getDeclaredAnnotations() : element.getAnnotations()); - for (Annotation annotation : annotations) { - if (annotation.annotationType().getName().equals(annotationType) || metaDepth > 0) { - T result = processor.process(annotation, metaDepth); - if (result != null) { - return result; - } - result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy, - processor, visited, metaDepth + 1); - if (result != null) { - processor.postProcess(annotation, result); - return result; + try { + Annotation[] annotations = + (traverseClassHierarchy ? element.getDeclaredAnnotations() : element.getAnnotations()); + for (Annotation annotation : annotations) { + if (annotation.annotationType().getName().equals(annotationType) || metaDepth > 0) { + T result = processor.process(annotation, metaDepth); + if (result != null) { + return result; + } + result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy, + processor, visited, metaDepth + 1); + if (result != null) { + processor.postProcess(annotation, result); + return result; + } } } - } - for (Annotation annotation : annotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { - T result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy, - processor, visited, metaDepth); - if (result != null) { - processor.postProcess(annotation, result); - return result; + for (Annotation annotation : annotations) { + if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { + T result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy, + processor, visited, metaDepth); + if (result != null) { + processor.postProcess(annotation, result); + return result; + } } } - } - if (traverseClassHierarchy && element instanceof Class) { - Class superclass = ((Class) element).getSuperclass(); - if (superclass != null && !superclass.equals(Object.class)) { - T result = doProcess(superclass, annotationType, true, processor, visited, metaDepth); - if (result != null) { - return result; + if (traverseClassHierarchy && element instanceof Class) { + Class superclass = ((Class) element).getSuperclass(); + if (superclass != null && !superclass.equals(Object.class)) { + T result = doProcess(superclass, annotationType, true, processor, visited, metaDepth); + if (result != null) { + return result; + } } } } + catch (Exception ex) { + AnnotationUtils.logIntrospectionFailure(element, ex); + } } return null; } @@ -232,7 +237,7 @@ public class AnnotatedElementUtils { * Callback interface used to process an annotation. * @param the result type */ - private static interface Processor { + private interface Processor { /** * Called to process the annotation. diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index 687a8cd8a92..6a427440ee2 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -613,7 +613,7 @@ public abstract class AnnotationUtils { value = ((Class) value).getName(); } else if (value instanceof Class[]) { - Class[] clazzArray = (Class[]) value; + Class[] clazzArray = (Class[]) value; String[] newValue = new String[clazzArray.length]; for (int i = 0; i < clazzArray.length; i++) { newValue[i] = clazzArray[i].getName(); @@ -726,14 +726,30 @@ public abstract class AnnotationUtils { } - private static void logIntrospectionFailure(AnnotatedElement annotatedElement, Exception ex) { + /** + * Log an introspection failure (in particular {@code TypeNotPresentExceptions}) - + * before moving on, pretending there were no annotations on this specific element. + * @param element the element that we tried to introspect annotations on + * @param ex the exception that we encountered + */ + static void logIntrospectionFailure(AnnotatedElement element, Exception ex) { Log loggerToUse = logger; if (loggerToUse == null) { loggerToUse = LogFactory.getLog(AnnotationUtils.class); logger = loggerToUse; } - if (loggerToUse.isInfoEnabled()) { - loggerToUse.info("Failed to introspect annotations on [" + annotatedElement + "]: " + ex); + if (element instanceof Class && Annotation.class.isAssignableFrom((Class) element)) { + // Meta-annotation lookup on an annotation type + if (logger.isDebugEnabled()) { + logger.debug("Failed to introspect meta-annotations on [" + element + "]: " + ex); + } + } + else { + // Direct annotation lookup on regular Class, Method, Field + if (loggerToUse.isInfoEnabled()) { + logger.info("Failed to introspect annotations on [" + element + "]: " + ex); + } + } } @@ -793,19 +809,24 @@ public abstract class AnnotationUtils { } @SuppressWarnings("unchecked") - private void process(AnnotatedElement annotatedElement) { - if (this.visited.add(annotatedElement)) { - for (Annotation ann : annotatedElement.getAnnotations()) { - if (ObjectUtils.nullSafeEquals(this.annotationType, ann.annotationType())) { - this.result.add((A) ann); - } - else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, ann.annotationType())) { - this.result.addAll(getValue(ann)); - } - else if (!isInJavaLangAnnotationPackage(ann)) { - process(ann.annotationType()); + private void process(AnnotatedElement element) { + if (this.visited.add(element)) { + try { + for (Annotation ann : element.getAnnotations()) { + if (ObjectUtils.nullSafeEquals(this.annotationType, ann.annotationType())) { + this.result.add((A) ann); + } + else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, ann.annotationType())) { + this.result.addAll(getValue(ann)); + } + else if (!isInJavaLangAnnotationPackage(ann)) { + process(ann.annotationType()); + } } } + catch (Exception ex) { + logIntrospectionFailure(element, ex); + } } }