Class ReflectionAnnotations
AnnotationMetadata and AnnotationValues from the annotations read reflectively from an
AnnotatedElement, in the shape the annotation processors give the metadata they generate at
compilation time.
Code written against generated metadata then works unchanged for an element that has none:
- the meta-annotations of an annotation are its stereotypes, recursively, with their values;
- a repeatable annotation is filed under its container, whether it was written once, several times or
inside the container, and the container is registered so that
AnnotationMetadata.getAnnotationValuesByType(Class)finds it; - the defaults of the members are registered and reachable through
AnnotationMetadata.getDefaultValues(String)and the value accessors; - a class value is an
AnnotationClassValue, an enum value is its name, a nested annotation is anAnnotationValue; - the members annotated
NonBindingare recorded, so that a qualifier built from the metadata ignores them; - an annotation a class inherits through
Inheritedis present but not declared, from a super class as from an interface of its hierarchy, which the processors walk andClass.getAnnotations()leaves out.
An annotation instance does not say which members were written, so a member whose value equals its default is not part of the values of the annotation; it is served by the defaults, as a member that was not written is at compilation time.
The annotation mappers, transformers and remappers of the annotation processors are not applied: they
are part of micronaut-core-processor and are not on a runtime classpath. The
ReflectionAnnotationCustomizer services are their runtime counterpart, and receive the values of
every annotation this class converts.
- Since:
- 5.2.0
- Author:
- Denis Stepanov
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidadd(MutableAnnotationMetadata metadata, Annotation annotation, boolean declared) Adds one annotation instance to a metadata under construction, asadd(MutableAnnotationMetadata, AnnotatedElement)adds every annotation of an element: a caller keeping only some annotations of an element - the constraints, the qualifiers - filters the instances and adds the ones it keeps.static voidadd(MutableAnnotationMetadata metadata, AnnotatedElement element) Adds the annotations of an element to a metadata under construction.static List<Annotation> contained(Annotation annotation) The annotations a repeatable container holds.static voiddeclare(MutableAnnotationMetadata metadata, Class<? extends Annotation> annotationType, Map<CharSequence, Object> values) Adds an annotation type, the values given, its defaults and its stereotypes to a metadata under construction.static AnnotationMetadatadeclaring(Class<? extends Annotation> annotationType) The metadata of an element that declares an annotation type with the defaults of its members.static AnnotationMetadatadeclaring(Class<? extends Annotation> annotationType, Map<CharSequence, Object> values) The metadata of an element that declares an annotation type, without an instance of it: the annotation with the values given, its defaults and its stereotypes, as the processors record it.static Map<CharSequence, Object> defaultValues(Class<? extends Annotation> annotationType) The defaults of the members of an annotation type, in the shapesvalues(Annotation)gives the values.static AnnotationMetadatamerge(AnnotationMetadata first, AnnotationMetadata second) The annotations of two metadata in one, both declared: the metadata of a class together with the annotations another container means it to carry.static AnnotationMetadatametadataOf(Annotation... annotations) Builds the metadata of annotation instances, each declared: the annotations a specification API hands over as an array, such as the ones of a JAX-RS entity or the qualifiers of a CDI lookup.static AnnotationMetadatametadataOf(@Nullable AnnotatedElement... elements) Builds the metadata of several elements merged, the first element first: the field, the getter and the setter of a property, or a parameter and its type.static AnnotationMetadatametadataOf(AnnotatedElement element) Builds the metadata of an element.static <A extends Annotation>
Asynthesize(AnnotationValue<A> annotationValue, ClassLoader classLoader) Builds an annotation instance from an annotation value, the type resolved by name through a class loader.static <A extends Annotation>
Asynthesize(Class<A> annotationType, AnnotationValue<A> annotationValue) Builds an annotation instance from an annotation value: the reverse ofvalueOf(Annotation).static <A extends Annotation>
AnnotationValue<A> valueOf(A annotation) The annotation value of an annotation instance, carrying its defaults.static <A extends Annotation>
AnnotationValue<A> valueOf(A annotation, @Nullable Consumer<Map<CharSequence, Object>> customizer) The annotation value of an annotation instance, carrying its defaults, with its values customized.static Map<CharSequence, Object> values(Annotation annotation) The values of the members of an annotation, as the metadata stores them: the members whose value is the default of the member are left out, a class is anAnnotationClassValue, an enum constant is its name, a nested annotation is anAnnotationValueand the members annotatedNonBindingare listed underAnnotationUtil.NON_BINDING_ATTRIBUTE.
-
Method Details
-
metadataOf
Builds the metadata of an element.- Parameters:
element- The element- Returns:
- The metadata,
AnnotationMetadata.EMPTY_METADATAwhen the element has no annotation
-
metadataOf
Builds the metadata of several elements merged, the first element first: the field, the getter and the setter of a property, or a parameter and its type.- Parameters:
elements- The elements, anullelement skipped- Returns:
- The metadata,
AnnotationMetadata.EMPTY_METADATAwhen none of the elements has an annotation
-
metadataOf
Builds the metadata of annotation instances, each declared: the annotations a specification API hands over as an array, such as the ones of a JAX-RS entity or the qualifiers of a CDI lookup.- Parameters:
annotations- The annotations- Returns:
- The metadata,
AnnotationMetadata.EMPTY_METADATAwhen there is no annotation
-
declaring
public static AnnotationMetadata declaring(Class<? extends Annotation> annotationType, Map<CharSequence, Object> values) The metadata of an element that declares an annotation type, without an instance of it: the annotation with the values given, its defaults and its stereotypes, as the processors record it.Code that adapts another container - a Guice binding annotation, a Spring bean marked primary - knows the annotation type and the members it means, and has no instance to read. Declaring the annotation by name alone loses its defaults and its stereotypes, and a qualifier built from such metadata then fails to match one built from the generated metadata of a bean.
- Parameters:
annotationType- The annotation type, filed under its container when it is repeatablevalues- The values of the members, empty when the annotation is written bare- Returns:
- The metadata
-
declaring
The metadata of an element that declares an annotation type with the defaults of its members.- Parameters:
annotationType- The annotation type- Returns:
- The metadata
- See Also:
-
declare
public static void declare(MutableAnnotationMetadata metadata, Class<? extends Annotation> annotationType, Map<CharSequence, Object> values) Adds an annotation type, the values given, its defaults and its stereotypes to a metadata under construction.- Parameters:
metadata- The metadataannotationType- The annotation typevalues- The values of the members, empty when the annotation is written bare- See Also:
-
merge
The annotations of two metadata in one, both declared: the metadata of a class together with the annotations another container means it to carry.A container adapting another one - a Spring bean it marks primary, a Guice binding it qualifies - has annotations of its own to add to the ones a class declares. Replacing the metadata of the class loses what the class says; a
hierarchykeeps both but only the last level counts as declared, and the framework reads a scope, a qualifier and a primary marker from the declared level. This merges them, so both are declared.- Parameters:
first- The metadata whose values win where both declare the same annotationsecond- The metadata to add- Returns:
- The merged metadata
-
add
Adds the annotations of an element to a metadata under construction. An annotation whose values cannot be read is left out, with a message logged at debug level: the generated metadata of an element records it, and the element must not lose the annotations that can be read because of it.- Parameters:
metadata- The metadataelement- The element
-
add
Adds one annotation instance to a metadata under construction, asadd(MutableAnnotationMetadata, AnnotatedElement)adds every annotation of an element: a caller keeping only some annotations of an element - the constraints, the qualifiers - filters the instances and adds the ones it keeps.- Parameters:
metadata- The metadataannotation- The annotationdeclared- Whether the annotation is declared on the element rather than inherited
-
contained
The annotations a repeatable container holds.- Parameters:
annotation- The annotation- Returns:
- The contained annotations, empty when the annotation is not the container of a repeatable annotation
-
values
The values of the members of an annotation, as the metadata stores them: the members whose value is the default of the member are left out, a class is anAnnotationClassValue, an enum constant is its name, a nested annotation is anAnnotationValueand the members annotatedNonBindingare listed underAnnotationUtil.NON_BINDING_ATTRIBUTE.A nested annotation is given the same treatment as the annotation holding it, recursively, and an array value is a copy the caller owns.
- Parameters:
annotation- The annotation- Returns:
- The values, mutable
- Throws:
IllegalStateException- When a member of the annotation cannot be read
-
defaultValues
The defaults of the members of an annotation type, in the shapesvalues(Annotation)gives the values.- Parameters:
annotationType- The annotation type- Returns:
- The defaults, unmodifiable
-
valueOf
The annotation value of an annotation instance, carrying its defaults. An instance that is anAnnotationValueProvider- a synthetic annotation built from a value - returns that value.- Type Parameters:
A- The annotation type- Parameters:
annotation- The annotation- Returns:
- The annotation value
-
valueOf
public static <A extends Annotation> AnnotationValue<A> valueOf(A annotation, @Nullable Consumer<Map<CharSequence, Object>> customizer) The annotation value of an annotation instance, carrying its defaults, with its values customized.- Type Parameters:
A- The annotation type- Parameters:
annotation- The annotationcustomizer- The customizer of the values, receiving a mutable copy, can benull- Returns:
- The annotation value
-
synthesize
public static <A extends Annotation> A synthesize(Class<A> annotationType, AnnotationValue<A> annotationValue) Builds an annotation instance from an annotation value: the reverse ofvalueOf(Annotation). The instance implementsAnnotationValueProvider, so that converting it back yields the value it was built from, and its members are the values of the annotation value completed by the defaults of the type.- Type Parameters:
A- The annotation type- Parameters:
annotationType- The annotation typeannotationValue- The annotation value- Returns:
- The annotation
-
synthesize
public static <A extends Annotation> A synthesize(AnnotationValue<A> annotationValue, ClassLoader classLoader) Builds an annotation instance from an annotation value, the type resolved by name through a class loader.- Type Parameters:
A- The annotation type- Parameters:
annotationValue- The annotation valueclassLoader- The class loader defining the annotation type- Returns:
- The annotation
- Throws:
IllegalArgumentException- When the class loader does not define the annotation type
-