Consistent detection of Order annotation in superclasses and interfaces
Issue: SPR-10514
This commit is contained in:
parent
16548d23e9
commit
814d24e64f
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,6 +19,7 @@ package org.springframework.aop.aspectj.annotation;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||||
if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
|
if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
|
||||||
return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
|
return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
|
||||||
}
|
}
|
||||||
Order order = type.getAnnotation(Order.class);
|
Order order = AnnotationUtils.findAnnotation(type, Order.class);
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
return order.value();
|
return order.value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.aop.aspectj.annotation;
|
||||||
|
|
||||||
import org.springframework.aop.aspectj.SimpleAspectInstanceFactory;
|
import org.springframework.aop.aspectj.SimpleAspectInstanceFactory;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +60,7 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
||||||
Order order = aspectClass.getAnnotation(Order.class);
|
Order order = AnnotationUtils.findAnnotation(aspectClass, Order.class);
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
return order.value();
|
return order.value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.aop.aspectj.annotation;
|
||||||
|
|
||||||
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
|
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +61,7 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
||||||
Order order = aspectClass.getAnnotation(Order.class);
|
Order order = AnnotationUtils.findAnnotation(aspectClass, Order.class);
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
return order.value();
|
return order.value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class AnnotationAwareOrderComparator extends OrderComparator {
|
||||||
}
|
}
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
Class<?> clazz = (obj instanceof Class ? (Class) obj : obj.getClass());
|
Class<?> clazz = (obj instanceof Class ? (Class) obj : obj.getClass());
|
||||||
Order order = clazz.getAnnotation(Order.class);
|
Order order = AnnotationUtils.findAnnotation(clazz, Order.class);
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
return order.value();
|
return order.value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.springframework.core.annotation;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.AnnotatedElement;
|
import java.lang.reflect.AnnotatedElement;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
@ -121,24 +120,24 @@ public abstract class AnnotationUtils {
|
||||||
*/
|
*/
|
||||||
public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
|
public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
|
||||||
A annotation = getAnnotation(method, annotationType);
|
A annotation = getAnnotation(method, annotationType);
|
||||||
Class<?> cl = method.getDeclaringClass();
|
Class<?> clazz = method.getDeclaringClass();
|
||||||
if (annotation == null) {
|
if (annotation == null) {
|
||||||
annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces());
|
annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
|
||||||
}
|
}
|
||||||
while (annotation == null) {
|
while (annotation == null) {
|
||||||
cl = cl.getSuperclass();
|
clazz = clazz.getSuperclass();
|
||||||
if (cl == null || cl == Object.class) {
|
if (clazz == null || clazz.equals(Object.class)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Method equivalentMethod = cl.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||||
annotation = getAnnotation(equivalentMethod, annotationType);
|
annotation = getAnnotation(equivalentMethod, annotationType);
|
||||||
}
|
}
|
||||||
catch (NoSuchMethodException ex) {
|
catch (NoSuchMethodException ex) {
|
||||||
// No equivalent method found
|
// No equivalent method found
|
||||||
}
|
}
|
||||||
if (annotation == null) {
|
if (annotation == null) {
|
||||||
annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces());
|
annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return annotation;
|
return annotation;
|
||||||
|
@ -217,7 +216,7 @@ public abstract class AnnotationUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Class<?> superClass = clazz.getSuperclass();
|
Class<?> superClass = clazz.getSuperclass();
|
||||||
if (superClass == null || superClass == Object.class) {
|
if (superClass == null || superClass.equals(Object.class)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return findAnnotation(superClass, annotationType);
|
return findAnnotation(superClass, annotationType);
|
||||||
|
@ -273,25 +272,22 @@ public abstract class AnnotationUtils {
|
||||||
* @return the first {@link Class} in the inheritance hierarchy of the specified
|
* @return the first {@link Class} in the inheritance hierarchy of the specified
|
||||||
* {@code clazz} which declares an annotation of at least one of the specified
|
* {@code clazz} which declares an annotation of at least one of the specified
|
||||||
* {@code annotationTypes}, or {@code null} if not found
|
* {@code annotationTypes}, or {@code null} if not found
|
||||||
|
* @since 3.2.2
|
||||||
* @see Class#isAnnotationPresent(Class)
|
* @see Class#isAnnotationPresent(Class)
|
||||||
* @see Class#getDeclaredAnnotations()
|
* @see Class#getDeclaredAnnotations()
|
||||||
* @see #findAnnotationDeclaringClass(Class, Class)
|
* @see #findAnnotationDeclaringClass(Class, Class)
|
||||||
* @see #isAnnotationDeclaredLocally(Class, Class)
|
* @see #isAnnotationDeclaredLocally(Class, Class)
|
||||||
* @since 3.2.2
|
|
||||||
*/
|
*/
|
||||||
public static Class<?> findAnnotationDeclaringClassForTypes(List<Class<? extends Annotation>> annotationTypes,
|
public static Class<?> findAnnotationDeclaringClassForTypes(List<Class<? extends Annotation>> annotationTypes, Class<?> clazz) {
|
||||||
Class<?> clazz) {
|
|
||||||
Assert.notEmpty(annotationTypes, "The list of annotation types must not be empty");
|
Assert.notEmpty(annotationTypes, "The list of annotation types must not be empty");
|
||||||
if (clazz == null || clazz.equals(Object.class)) {
|
if (clazz == null || clazz.equals(Object.class)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Class<? extends Annotation> annotationType : annotationTypes) {
|
for (Class<? extends Annotation> annotationType : annotationTypes) {
|
||||||
if (isAnnotationDeclaredLocally(annotationType, clazz)) {
|
if (isAnnotationDeclaredLocally(annotationType, clazz)) {
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return findAnnotationDeclaringClassForTypes(annotationTypes, clazz.getSuperclass());
|
return findAnnotationDeclaringClassForTypes(annotationTypes, clazz.getSuperclass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,16 @@ public class AnnotationAwareOrderComparatorTests {
|
||||||
assertTrue(list.get(1) instanceof B);
|
assertTrue(list.get(1) instanceof B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sortInstancesWithSubclass() {
|
||||||
|
List<Object> list = new ArrayList<>();
|
||||||
|
list.add(new B());
|
||||||
|
list.add(new C());
|
||||||
|
AnnotationAwareOrderComparator.sort(list);
|
||||||
|
assertTrue(list.get(0) instanceof C);
|
||||||
|
assertTrue(list.get(1) instanceof B);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sortClasses() {
|
public void sortClasses() {
|
||||||
List<Object> list = new ArrayList<>();
|
List<Object> list = new ArrayList<>();
|
||||||
|
@ -55,6 +65,16 @@ public class AnnotationAwareOrderComparatorTests {
|
||||||
assertEquals(B.class, list.get(1));
|
assertEquals(B.class, list.get(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sortClassesWithSubclass() {
|
||||||
|
List<Object> list = new ArrayList<>();
|
||||||
|
list.add(B.class);
|
||||||
|
list.add(C.class);
|
||||||
|
AnnotationAwareOrderComparator.sort(list);
|
||||||
|
assertEquals(C.class, list.get(0));
|
||||||
|
assertEquals(B.class, list.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Order(1)
|
@Order(1)
|
||||||
private static class A {
|
private static class A {
|
||||||
|
@ -64,4 +84,7 @@ public class AnnotationAwareOrderComparatorTests {
|
||||||
private static class B {
|
private static class B {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class C extends A {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue