Improve performance for synthesizing a single annotation instance #24981
Labels
in: core
Issues in core modules (aop, beans, core, context, expression)
status: declined
A suggestion or change that we don't feel we should currently apply
type: regression
A bug that is also a regression
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 offindMergedAnnotation()
. Similarly, the internal data structures in theMergedAnnotation
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 viaSynthesizingMethodParameter
, which delegates toAnnotationUtils.synthesizeAnnotation()
to support the use of@AliasFor
.In 5.2.x, this is implemented using
MergedAnnotation.from(...)
:spring-framework/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
Lines 1188 to 1195 in 73fadd8
Whereas, in 5.1.x, this is implemented using the
DefaultAnnotationAttributeExtractor
:spring-framework/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
Lines 1556 to 1574 in ea7b010
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 sinceTypeMappedAnnotation.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 asSynthesizingMethodParameter
.The text was updated successfully, but these errors were encountered: