Based on the findings in #24961 and #24970, it appears that we can improve the runtime performance for method parameter annotations synthesized due to their use of @AliasFor.

Annotations such as @RequestParam can only be declared directly on parameters (due to the @Target(ElementType.PARAMETER) declaration). Consequently, they can never be merged in the sense of findMergedAnnotation(). Similarly, the internal data structures in the MergedAnnotation API that support annotation attribute overriding (i.e., "merging") are never used for such annotations.

In addition, within the Spring Framework, @RequestParam is only looked up via SynthesizingMethodParameter, which delegates to AnnotationUtils.synthesizeAnnotation() to support the use of @AliasFor.

In 5.2.x, this is implemented using MergedAnnotation.from(...):

https://github.com/spring-projects/spring-framework/blob/73fadd8b7c02938a0155ff49a40b4257092d1dc4/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java#L1188-L1195

Whereas, in 5.1.x, this is implemented using the DefaultAnnotationAttributeExtractor:

https://github.com/spring-projects/spring-framework/blob/ea7b0103c5b9ab403b75197f5f1f4582c85eb2fd/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java#L1556-L1574

The major difference here is that direct use of DefaultAnnotationAttributeExtractor avoids any extra overhead incurred by searching for annotation attribute overrides. In addition, DefaultAnnotationAttributeExtractor uses a direct approach for accessing the non-aliased values of the original annotation, thereby avoiding any complex lookups, conversions, adaptations, etc.

For example, if we still had a direct lookup mechanism for the required attribute in @RequestParam, then #24961 never would have surfaced as a regression since TypeMappedAnnotation.getValue(...) would not come into play.

In summary, the use of the MergedAnnotation API for direct synthesis of a single annotation without any form of attribute override support results in unnecessary runtime overhead and a regression in performance in Spring Framework 5.2.x.

We should therefore consider reintroducing the DefaultAnnotationAttributeExtractor / MapAnnotationAttributeExtractor dichotomy that existed prior to 5.2, or we should investigate an alternative means for synthesizing an annotation directly from a concrete annotation instance with limited support for @AliasFor for locally aliased attributes as is needed by clients such as SynthesizingMethodParameter.

Comment From: sbrannen

Closing this issue since there have been no reports from the community regarding regressions in performance.

We may revisit this at a later date if we receive reports of performance regressions.