Avoid synthesizing annotations unnecessarily

Prior to Spring Framework 5.2, some of our annotation utilities would
not synthesize an annotation if it was already synthesized or not
synthesizable (i.e., did not declare local aliases via @AliasFor and
did not declare attributes that could override attributes in the
meta-annotation hierarchy above the given annotation); however, we lost
most of this functionality with the introduction of the new
MergedAnnotations API.

This commit revises the implementation of createSynthesized() in
TypeMappedAnnotation so that, for invocations of
MergedAnnotation.synthesize() and indirectly for invocations of
AnnotatedElementUtils.findMergedAnnotation(), etc.:

1. An annotation that was previously synthesized will not be
   synthesized again.

2. An annotation that is not "synthesizable" will not be synthesized.

For both of the above use cases, the original annotation is now
returned from createSynthesized().

Closes gh-24861
This commit is contained in:
Sam Brannen
2020-04-20 15:30:48 +02:00
parent 8d31dcaa29
commit 31fa1569c5
2 changed files with 68 additions and 0 deletions

View File

@@ -329,7 +329,18 @@ final class TypeMappedAnnotation<A extends Annotation> extends AbstractMergedAnn
}
@Override
@SuppressWarnings("unchecked")
protected A createSynthesized() {
if (this.rootAttributes instanceof Annotation) {
// Nothing to synthesize?
if (this.resolvedRootMirrors.length == 0 && this.resolvedMirrors.length == 0) {
return (A) this.rootAttributes;
}
// Already synthesized?
if (this.rootAttributes instanceof SynthesizedAnnotation) {
return (A) this.rootAttributes;
}
}
return SynthesizedMergedAnnotationInvocationHandler.createProxy(this, getType());
}