diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java index 3c4417cbe4..c5463b1461 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java @@ -42,7 +42,6 @@ import org.springframework.aop.framework.AopConfigException; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; /** * Abstract base class for factories that can create Spring AOP Advisors @@ -60,6 +59,9 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac private static final String AJC_MAGIC = "ajc$"; + private static final Class[] ASPECTJ_ANNOTATION_CLASSES = new Class[] { + Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}; + /** Logger available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); @@ -128,9 +130,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac @SuppressWarnings("unchecked") @Nullable protected static AspectJAnnotation findAspectJAnnotationOnMethod(Method method) { - Class[] classesToLookFor = new Class[] { - Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; - for (Class clazz : classesToLookFor) { + for (Class clazz : ASPECTJ_ANNOTATION_CLASSES) { AspectJAnnotation foundAnnotation = findAnnotation(method, (Class) clazz); if (foundAnnotation != null) { return foundAnnotation; @@ -152,16 +152,12 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac /** - * AspectJ annotation types. + * Enum for AspectJ annotation types. + * @see AspectJAnnotation#getAnnotationType() */ protected enum AspectJAnnotationType { - AtPointcut, - AtBefore, - AtAfter, - AtAfterReturning, - AtAfterThrowing, - AtAround + AtPointcut, AtAround, AtBefore, AtAfter, AtAfterReturning, AtAfterThrowing } @@ -172,17 +168,17 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac */ protected static class AspectJAnnotation { - private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"}; + private static final String[] EXPRESSION_ATTRIBUTES = new String[] {"pointcut", "value"}; - private static Map, AspectJAnnotationType> annotationTypes = new HashMap<>(); + private static Map, AspectJAnnotationType> annotationTypeMap = new HashMap<>(8); static { - annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut); - annotationTypes.put(After.class,AspectJAnnotationType.AtAfter); - annotationTypes.put(AfterReturning.class,AspectJAnnotationType.AtAfterReturning); - annotationTypes.put(AfterThrowing.class,AspectJAnnotationType.AtAfterThrowing); - annotationTypes.put(Around.class,AspectJAnnotationType.AtAround); - annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore); + annotationTypeMap.put(Pointcut.class, AspectJAnnotationType.AtPointcut); + annotationTypeMap.put(Around.class, AspectJAnnotationType.AtAround); + annotationTypeMap.put(Before.class, AspectJAnnotationType.AtBefore); + annotationTypeMap.put(After.class, AspectJAnnotationType.AtAfter); + annotationTypeMap.put(AfterReturning.class, AspectJAnnotationType.AtAfterReturning); + annotationTypeMap.put(AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing); } private final A annotation; @@ -196,40 +192,31 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac public AspectJAnnotation(A annotation) { this.annotation = annotation; this.annotationType = determineAnnotationType(annotation); - // We know these methods exist with the same name on each object, - // but need to invoke them reflectively as there isn't a common interface. try { this.pointcutExpression = resolveExpression(annotation); - this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation); + Object argNames = AnnotationUtils.getValue(annotation, "argNames"); + this.argumentNames = (argNames instanceof String ? (String) argNames : ""); } catch (Exception ex) { - throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex); + throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex); } } private AspectJAnnotationType determineAnnotationType(A annotation) { - for (Map.Entry, AspectJAnnotationType> typeEntry : annotationTypes.entrySet()) { - Class type = typeEntry.getKey(); - if (type.isInstance(annotation)) { - return typeEntry.getValue(); - } + AspectJAnnotationType type = annotationTypeMap.get(annotation.annotationType()); + if (type != null) { + return type; } - throw new IllegalStateException("Unknown annotation type: " + annotation.toString()); + throw new IllegalStateException("Unknown annotation type: " + annotation); } - private String resolveExpression(A annotation) throws Exception { - for (String methodName : EXPRESSION_PROPERTIES) { - Method method; - try { - method = annotation.getClass().getDeclaredMethod(methodName); - } - catch (NoSuchMethodException ex) { - method = null; - } - if (method != null) { - String candidate = (String) method.invoke(annotation); - if (StringUtils.hasText(candidate)) { - return candidate; + private String resolveExpression(A annotation) { + for (String attributeName : EXPRESSION_ATTRIBUTES) { + Object val = AnnotationUtils.getValue(annotation, attributeName); + if (val instanceof String) { + String str = (String) val; + if (!str.isEmpty()) { + return str; } } } @@ -275,11 +262,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac if (annotation == null) { return null; } - StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ","); - if (strTok.countTokens() > 0) { - String[] names = new String[strTok.countTokens()]; + StringTokenizer nameTokens = new StringTokenizer(annotation.getArgumentNames(), ","); + if (nameTokens.countTokens() > 0) { + String[] names = new String[nameTokens.countTokens()]; for (int i = 0; i < names.length; i++) { - names[i] = strTok.nextToken(); + names[i] = nameTokens.nextToken(); } return names; } 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 94e9d648b9..2d04f8ee9a 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 @@ -1417,6 +1417,9 @@ public abstract class AnnotationUtils { ReflectionUtils.makeAccessible(method); return method.invoke(annotation); } + catch (NoSuchMethodException ex) { + return null; + } catch (InvocationTargetException ex) { rethrowAnnotationConfigurationException(ex.getTargetException()); throw new IllegalStateException(