下面列出了java.lang.reflect.AnnotatedElement#getDeclaredAnnotation ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Find a single {@link Annotation} of {@code annotationType} on the
* supplied {@link AnnotatedElement}.
* <p>Meta-annotations will be searched if the annotation is not
* <em>directly present</em> on the supplied element.
* <p><strong>Warning</strong>: this method operates generically on
* annotated elements. In other words, this method does not execute
* specialized search algorithms for classes or methods. If you require
* the more specific semantics of {@link #findAnnotation(Class, Class)}
* or {@link #findAnnotation(Method, Class)}, invoke one of those methods
* instead.
* @param annotatedElement the {@code AnnotatedElement} on which to find the annotation
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
* @return the first matching annotation, or {@code null} if not found
* @since 4.2
*/
@Nullable
public static <A extends Annotation> A findAnnotation(
AnnotatedElement annotatedElement, @Nullable Class<A> annotationType) {
if (annotationType == null) {
return null;
}
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
return annotatedElement.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN)
.get(annotationType).withNonMergedAttributes()
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
/**
* Perform the search algorithm for {@link #findAnnotation(AnnotatedElement, Class)}
* avoiding endless recursion by tracking which annotations have already
* been <em>visited</em>.
* @param annotatedElement the {@code AnnotatedElement} on which to find the annotation
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
* @param visited the set of annotations that have already been visited
* @return the first matching annotation, or {@code null} if not found
* @since 4.2
*/
@Nullable
private static <A extends Annotation> A findAnnotation(
AnnotatedElement annotatedElement, Class<A> annotationType, Set<Annotation> visited) {
try {
A annotation = annotatedElement.getDeclaredAnnotation(annotationType);
if (annotation != null) {
return annotation;
}
for (Annotation declaredAnn : getDeclaredAnnotations(annotatedElement)) {
Class<? extends Annotation> declaredType = declaredAnn.annotationType();
if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
annotation = findAnnotation((AnnotatedElement) declaredType, annotationType, visited);
if (annotation != null) {
return annotation;
}
}
}
}
catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex);
}
return null;
}
/**
* Test the {@link AnnotatedElement} methods associated with "direct" annotations.
*
* <p>Asserts that calling {@link AnnotatedElement#getDeclaredAnnotations()} on the supplied
* element returns annotations of the supplied expected classes.
*
* <p>Where the expected classes contains some subset from
* {@link AnnotationA}, {@link AnnotationB} and {@link AnnotationC}, this method also asserts
* that {@link AnnotatedElement#getDeclaredAnnotation(Class)} works as expected.
*
* <p>This method also confirms that {@link AnnotatedElement#isAnnotationPresent(Class)} and
* {@link AnnotatedElement#getAnnotation(Class)} work correctly with a {@code null} argument.
*/
static void checkAnnotatedElementDirectMethods(
AnnotatedElement element,
Class<? extends Annotation>... expectedDeclaredAnnotations) {
Set<Class<? extends Annotation>> actualTypes = annotationsToTypes(element.getDeclaredAnnotations());
Set<Class<? extends Annotation>> expectedTypes = set(expectedDeclaredAnnotations);
assertEquals(expectedTypes, actualTypes);
assertDeclared(expectedTypes.contains(AnnotationA.class), element, AnnotationA.class);
assertDeclared(expectedTypes.contains(AnnotationB.class), element, AnnotationB.class);
assertDeclared(expectedTypes.contains(AnnotationC.class), element, AnnotationC.class);
try {
element.getDeclaredAnnotation(null);
fail();
} catch (NullPointerException expected) {
}
}
@SuppressWarnings("unchecked")
public static <T extends Annotation> List<T> getDeclaredAnnotations(AnnotatedElement object, Class<T> annotationClass)
{
List<T> annotations = new LinkedList<>();
if (object == null || annotationClass == null)
{
return annotations;
}
// check if the annotation is repeatable
Repeatable repeatingAnnotation = annotationClass.getAnnotation(Repeatable.class);
Annotation annotation = (repeatingAnnotation == null) ? null : object.getDeclaredAnnotation(repeatingAnnotation.value());
if (annotation != null)
{
try
{
annotations.addAll(Arrays.asList((T[]) annotation.getClass().getMethod("value").invoke(annotation)));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
else
{
T anno = object.getDeclaredAnnotation(annotationClass);
if (anno != null)
{
annotations.add(anno);
}
}
return annotations;
}
private static String getFieldPath(Member m, AnnotatedElement e) {
FieldPath fpa = e.getDeclaredAnnotation(FieldPath.class);
if (fpa == null) {
return m.getName();
}
String fieldPath = e.getDeclaredAnnotation(FieldPath.class).value();
if (fieldPath.isEmpty()) {
return m.getName();
}
return fieldPath;
}
/**
* Gets the annotated path (specified with @Path or @AdvancedPath) of an annotated element.
*
* @return the annotated path, or {@code null} if there is none.
*/
static String[] getPath(AnnotatedElement annotatedElement) {
Path path = annotatedElement.getDeclaredAnnotation(Path.class);
if (path != null) {
return StringUtils.split(path.value(), '.');
}
AdvancedPath advancedPath = annotatedElement.getDeclaredAnnotation(AdvancedPath.class);
if (advancedPath != null) {
return advancedPath.value();
}
return null;
}
public <T> T resolve(AnnotatedElement element, Class<T> elementType) throws Throwable {
DynamicClassLiteral dynamicClassLiteralRequest =
element.getDeclaredAnnotation(DynamicClassLiteral.class);
if (dynamicClassLiteralRequest != null) {
return elementType.cast(
loadClassLiteral(
dynamicClassLiteralRequest,
jarTransformationRecords,
inputClassLoader,
reflectionBasedMembers,
descriptorLookupRepo,
workingJavaPackage));
}
AsmNode asmNodeRequest = element.getDeclaredAnnotation(AsmNode.class);
if (asmNodeRequest != null) {
return getAsmNode(
asmNodeRequest, elementType, jarTransformationRecords, inputs, workingJavaPackage);
}
RuntimeMethodHandle runtimeMethodHandleRequest =
element.getDeclaredAnnotation(RuntimeMethodHandle.class);
if (runtimeMethodHandleRequest != null) {
return elementType.cast(
getMethodHandle(
runtimeMethodHandleRequest,
testInstanceLookup,
jarTransformationRecords,
inputClassLoader,
reflectionBasedMembers,
descriptorLookupRepo,
workingJavaPackage));
}
RuntimeJarEntry runtimeJarEntry = element.getDeclaredAnnotation(RuntimeJarEntry.class);
if (runtimeJarEntry != null) {
return elementType.cast(
getJarEntry(runtimeJarEntry, jarTransformationRecords, inputs, workingJavaPackage));
}
throw new UnsupportedOperationException(
"Expected one of the supported types for injection: " + SUPPORTED_QUALIFIERS);
}
/**
* Get the first annotation of the specified {@code annotationType} within
* the annotation hierarchy <em>above</em> the supplied {@code element},
* merge that annotation's attributes with <em>matching</em> attributes from
* annotations in lower levels of the annotation hierarchy, and synthesize
* the result back into an annotation of the specified {@code annotationType}.
* <p>{@link AliasFor @AliasFor} semantics are fully supported, both
* within a single annotation and within the annotation hierarchy.
* <p>This method delegates to {@link #getMergedAnnotationAttributes(AnnotatedElement, Class)}
* and {@link AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)}.
* @param element the annotated element
* @param annotationType the annotation type to find
* @return the merged, synthesized {@code Annotation}, or {@code null} if not found
* @since 4.2
* @see #getMergedAnnotationAttributes(AnnotatedElement, Class)
* @see #findMergedAnnotation(AnnotatedElement, Class)
* @see AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)
*/
@Nullable
public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
A annotation = element.getDeclaredAnnotation(annotationType);
if (annotation != null) {
return AnnotationUtils.synthesizeAnnotation(annotation, element);
}
// Shortcut: no searchable annotations to be found on plain Java classes and org.springframework.lang types...
if (AnnotationUtils.hasPlainJavaAnnotationsOnly(element)) {
return null;
}
// Exhaustive retrieval of merged annotation attributes...
AnnotationAttributes attributes = getMergedAnnotationAttributes(element, annotationType);
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
}
/**
* Find the first annotation of the specified {@code annotationType} within
* the annotation hierarchy <em>above</em> the supplied {@code element},
* merge that annotation's attributes with <em>matching</em> attributes from
* annotations in lower levels of the annotation hierarchy, and synthesize
* the result back into an annotation of the specified {@code annotationType}.
* <p>{@link AliasFor @AliasFor} semantics are fully supported, both
* within a single annotation and within the annotation hierarchy.
* <p>This method follows <em>find semantics</em> as described in the
* {@linkplain AnnotatedElementUtils class-level javadoc}.
* @param element the annotated element
* @param annotationType the annotation type to find
* @return the merged, synthesized {@code Annotation}, or {@code null} if not found
* @since 4.2
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
* @see #findMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean)
* @see #getMergedAnnotationAttributes(AnnotatedElement, Class)
*/
@Nullable
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
A annotation = element.getDeclaredAnnotation(annotationType);
if (annotation != null) {
return AnnotationUtils.synthesizeAnnotation(annotation, element);
}
// Shortcut: no searchable annotations to be found on plain Java classes and org.springframework.lang types...
if (AnnotationUtils.hasPlainJavaAnnotationsOnly(element)) {
return null;
}
// Exhaustive retrieval of merged annotation attributes...
AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationType, false, false);
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
}
/**
* Asserts that {@link AnnotatedElement#getDeclaredAnnotation(Class)} returns the expected
* result. The result is specified using a String. See {@link AnnotatedElementTestSupport} for
* the string syntax.
*/
static void assertGetDeclaredAnnotation(AnnotatedElement annotatedElement,
Class<? extends Annotation> annotationType, String expectedAnnotationString) {
Annotation annotation = annotatedElement.getDeclaredAnnotation(annotationType);
assertAnnotationMatches(annotation, expectedAnnotationString);
}
/**
* Get the first annotation of the specified {@code annotationType} within
* the annotation hierarchy <em>above</em> the supplied {@code element},
* merge that annotation's attributes with <em>matching</em> attributes from
* annotations in lower levels of the annotation hierarchy, and synthesize
* the result back into an annotation of the specified {@code annotationType}.
* <p>{@link AliasFor @AliasFor} semantics are fully supported, both
* within a single annotation and within the annotation hierarchy.
* @param element the annotated element
* @param annotationType the annotation type to find
* @return the merged, synthesized {@code Annotation}, or {@code null} if not found
* @since 4.2
* @see #findMergedAnnotation(AnnotatedElement, Class)
*/
@Nullable
public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return element.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return getAnnotations(element)
.get(annotationType, null, MergedAnnotationSelectors.firstDirectlyDeclared())
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
/**
* Find the first annotation of the specified {@code annotationType} within
* the annotation hierarchy <em>above</em> the supplied {@code element},
* merge that annotation's attributes with <em>matching</em> attributes from
* annotations in lower levels of the annotation hierarchy, and synthesize
* the result back into an annotation of the specified {@code annotationType}.
* <p>{@link AliasFor @AliasFor} semantics are fully supported, both
* within a single annotation and within the annotation hierarchy.
* <p>This method follows <em>find semantics</em> as described in the
* {@linkplain AnnotatedElementUtils class-level javadoc}.
* @param element the annotated element
* @param annotationType the annotation type to find
* @return the merged, synthesized {@code Annotation}, or {@code null} if not found
* @since 4.2
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
* @see #findMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean)
* @see #getMergedAnnotationAttributes(AnnotatedElement, Class)
*/
@Nullable
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return element.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return findAnnotations(element)
.get(annotationType, null, MergedAnnotationSelectors.firstDirectlyDeclared())
.synthesize(MergedAnnotation::isPresent).orElse(null);
}