|
|
|
@ -28,6 +28,7 @@ import java.util.List; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Test; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.Ordered; |
|
|
|
import org.springframework.core.Ordered; |
|
|
|
import org.springframework.core.annotation.subpackage.NonPublicAnnotatedClass; |
|
|
|
import org.springframework.core.annotation.subpackage.NonPublicAnnotatedClass; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
@ -37,6 +38,8 @@ import static org.junit.Assert.*; |
|
|
|
import static org.springframework.core.annotation.AnnotationUtils.*; |
|
|
|
import static org.springframework.core.annotation.AnnotationUtils.*; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
|
|
|
|
* Unit tests for {@link AnnotationUtils}. |
|
|
|
|
|
|
|
* |
|
|
|
* @author Rod Johnson |
|
|
|
* @author Rod Johnson |
|
|
|
* @author Juergen Hoeller |
|
|
|
* @author Juergen Hoeller |
|
|
|
* @author Sam Brannen |
|
|
|
* @author Sam Brannen |
|
|
|
@ -97,9 +100,9 @@ public class AnnotationUtilsTests { |
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void findAnnotationPrefersInteracesOverLocalMetaAnnotations() { |
|
|
|
public void findAnnotationPrefersInterfacesOverLocalMetaAnnotations() { |
|
|
|
Component component = AnnotationUtils.findAnnotation( |
|
|
|
Component component = AnnotationUtils.findAnnotation( |
|
|
|
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, Component.class); |
|
|
|
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, Component.class); |
|
|
|
|
|
|
|
|
|
|
|
// By inspecting ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface, one
|
|
|
|
// By inspecting ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface, one
|
|
|
|
// might expect that "meta2" should be found; however, with the current
|
|
|
|
// might expect that "meta2" should be found; however, with the current
|
|
|
|
@ -144,8 +147,7 @@ public class AnnotationUtilsTests { |
|
|
|
// inherited class-level annotation; note: @Transactional is inherited
|
|
|
|
// inherited class-level annotation; note: @Transactional is inherited
|
|
|
|
assertEquals(InheritedAnnotationInterface.class, |
|
|
|
assertEquals(InheritedAnnotationInterface.class, |
|
|
|
findAnnotationDeclaringClassForTypes(transactionalCandidateList, InheritedAnnotationInterface.class)); |
|
|
|
findAnnotationDeclaringClassForTypes(transactionalCandidateList, InheritedAnnotationInterface.class)); |
|
|
|
assertNull(findAnnotationDeclaringClassForTypes(transactionalCandidateList, |
|
|
|
assertNull(findAnnotationDeclaringClassForTypes(transactionalCandidateList, SubInheritedAnnotationInterface.class)); |
|
|
|
SubInheritedAnnotationInterface.class)); |
|
|
|
|
|
|
|
assertEquals(InheritedAnnotationClass.class, |
|
|
|
assertEquals(InheritedAnnotationClass.class, |
|
|
|
findAnnotationDeclaringClassForTypes(transactionalCandidateList, InheritedAnnotationClass.class)); |
|
|
|
findAnnotationDeclaringClassForTypes(transactionalCandidateList, InheritedAnnotationClass.class)); |
|
|
|
assertEquals(InheritedAnnotationClass.class, |
|
|
|
assertEquals(InheritedAnnotationClass.class, |
|
|
|
@ -301,8 +303,7 @@ public class AnnotationUtilsTests { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void findAnnotationFromInterfaceWhenSuperDoesNotImplementMethod() |
|
|
|
public void findAnnotationFromInterfaceWhenSuperDoesNotImplementMethod() throws Exception { |
|
|
|
throws Exception { |
|
|
|
|
|
|
|
Method method = SubOfAbstractImplementsInterfaceWithAnnotatedMethod.class.getMethod("foo"); |
|
|
|
Method method = SubOfAbstractImplementsInterfaceWithAnnotatedMethod.class.getMethod("foo"); |
|
|
|
Order order = findAnnotation(method, Order.class); |
|
|
|
Order order = findAnnotation(method, Order.class); |
|
|
|
assertNotNull(order); |
|
|
|
assertNotNull(order); |
|
|
|
@ -322,13 +323,13 @@ public class AnnotationUtilsTests { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Component(value = "meta1") |
|
|
|
@Component(value="meta1") |
|
|
|
@Order |
|
|
|
@Order |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
@interface Meta1 { |
|
|
|
@interface Meta1 { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Component(value = "meta2") |
|
|
|
@Component(value="meta2") |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
@interface Meta2 { |
|
|
|
@interface Meta2 { |
|
|
|
@ -353,25 +354,20 @@ public class AnnotationUtilsTests { |
|
|
|
|
|
|
|
|
|
|
|
@Order(27) |
|
|
|
@Order(27) |
|
|
|
public void annotatedOnRoot() { |
|
|
|
public void annotatedOnRoot() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void overrideToAnnotate() { |
|
|
|
public void overrideToAnnotate() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Order(27) |
|
|
|
@Order(27) |
|
|
|
public void overrideWithoutNewAnnotation() { |
|
|
|
public void overrideWithoutNewAnnotation() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void notAnnotated() { |
|
|
|
public void notAnnotated() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void fromInterfaceImplementedByRoot() { |
|
|
|
public void fromInterfaceImplementedByRoot() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -379,21 +375,23 @@ public class AnnotationUtilsTests { |
|
|
|
|
|
|
|
|
|
|
|
@Order(25) |
|
|
|
@Order(25) |
|
|
|
public void annotatedOnLeaf() { |
|
|
|
public void annotatedOnLeaf() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@Order(1) |
|
|
|
@Order(1) |
|
|
|
public void overrideToAnnotate() { |
|
|
|
public void overrideToAnnotate() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void overrideWithoutNewAnnotation() { |
|
|
|
public void overrideWithoutNewAnnotation() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Inherited |
|
|
|
|
|
|
|
@interface Transactional { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static abstract class Foo<T> { |
|
|
|
public static abstract class Foo<T> { |
|
|
|
|
|
|
|
|
|
|
|
@Order(1) |
|
|
|
@Order(1) |
|
|
|
@ -405,7 +403,6 @@ public class AnnotationUtilsTests { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
public void something(final String arg) { |
|
|
|
public void something(final String arg) { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -474,58 +471,45 @@ public class AnnotationUtilsTests { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public abstract static class AbstractDoesNotImplementInterfaceWithAnnotatedMethod implements |
|
|
|
public abstract static class AbstractDoesNotImplementInterfaceWithAnnotatedMethod |
|
|
|
InterfaceWithAnnotatedMethod { |
|
|
|
implements InterfaceWithAnnotatedMethod { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static class SubOfAbstractImplementsInterfaceWithAnnotatedMethod extends |
|
|
|
public static class SubOfAbstractImplementsInterfaceWithAnnotatedMethod |
|
|
|
AbstractDoesNotImplementInterfaceWithAnnotatedMethod { |
|
|
|
extends AbstractDoesNotImplementInterfaceWithAnnotatedMethod { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void foo() { |
|
|
|
public void foo() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static interface InterfaceWithRepeated { |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Inherited |
|
|
|
@MyRepeatable("a") |
|
|
|
@interface MyRepeatableContainer { |
|
|
|
@MyRepeatableContainer({ @MyRepeatable("b"), @MyRepeatable("c") }) |
|
|
|
|
|
|
|
@MyRepeatableMeta |
|
|
|
|
|
|
|
void foo(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MyRepeatable[] value(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Inherited |
|
|
|
|
|
|
|
@Repeatable(MyRepeatableContainer.class) |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
@interface MyRepeatable { |
|
|
|
@Inherited |
|
|
|
|
|
|
|
@interface Transactional { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Inherited |
|
|
|
|
|
|
|
@interface MyRepeatableContainer { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MyRepeatable[] value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
String value(); |
|
|
|
@Inherited |
|
|
|
} |
|
|
|
@Repeatable(MyRepeatableContainer.class) |
|
|
|
|
|
|
|
@interface MyRepeatable { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String value(); |
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Inherited |
|
|
|
|
|
|
|
@MyRepeatable("meta") |
|
|
|
|
|
|
|
@interface MyRepeatableMeta { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
public static interface InterfaceWithRepeated { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@MyRepeatable("a") |
|
|
|
|
|
|
|
@MyRepeatableContainer({ @MyRepeatable("b"), @MyRepeatable("c") }) |
|
|
|
|
|
|
|
@MyRepeatableMeta |
|
|
|
|
|
|
|
void foo(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Inherited |
|
|
|
|
|
|
|
@MyRepeatable("meta") |
|
|
|
|
|
|
|
@interface MyRepeatableMeta { |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|