Repository navigation
fix: Read class-level prefixes of composed controller annotations as Spring merges them (#672) - #690
Merged
Merged
Conversation
…Spring merges them (#672)
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
A controller annotated with a composed annotation such as
is served by Spring under
/api/..., but the plugin read the class-level prefix from the values written at the use site only, so@ApiController class ItemsControllerlost its prefix in the endpoint model and in every consumer of the class prefix. #673 added the merged-values resolver; this PR switches the class-level prefix to it. First caller group of #672.Change
HandlerMethods.requestMappingPrefixesreads the class mapping through the merged UAST API (MetaAnnotationsHolder/MergedAnnotationAttributesfrom fix: Read composed annotations as Spring merges them (#651) #673):@AliasFordefaults and use-site values, an alias tovalue, a second composed level, a meta-fixed path. An unaliased attribute named like a mapping path attribute (convention mapping) sets the prefix only when the Spring major is known and below 7, as Spring does; an unknown version applies no convention.@RequestMappingdescriptor of an element, ordered by meta-distance (RequestMappingHandlerMapping.createRequestMappingInfo, "only the first will be used"). The prefix is read from exactly that annotation: a direct@RequestMappingwins over a composed one in any source order; ties go to declaration order. NewMetaAnnotationsHolder.nearestAnnotation(+MergedAnnotationAttributes.metaDistanceOf) implements the rule.SpringWebControllerLoaderreusesrequestMappingPrefixesinstead of its own declared-only copy. When a class cannot be converted to UAST, the declared PSI values of the nearest annotation are read as before.Framework evidence
Probe on real jars (spring-webmvc / spring-webflux 6.2.19 and 7.0.9), prefix registered for each case:
path, default/api, bare/api/api/v2/v2/v2/x,/y/x,/yvalue, default/dval/dval/dval@RequestMapping("/fixed")/fixed/fixed/api/apipath(convention)/convNot in this PR (remaining #672 groups)
@RequestMappingreaders still on the declared PSI overload (gutters, OpenAPI endpoint info, duplicate mapping inspection), andSpringWebUtil.requestMappingOf, which merges values of every mapping annotation of a handler method instead of the nearest one.@HttpExchangeloader,@ConditionalOnBean/@ConditionalOnMissingBean,PropertyConditionSpecReader,OnWebApplicationCondition.Verification
value, two levels, convention on Spring 6,HandlerMethods; Java and Kotlin) and e716b94 (8 reds: a direct@RequestMappingbeside a composed one, both source orders, loader andHandlerMethods, Java and Kotlin).ComposedMappingDefaultPathTest15/15,ComposedControllerPrefixSpring7Test2/2, KotlinComposedControllerPrefixTest10/10; gutter, OpenAPI and loader suites 184/184;MetaAnnotationsHolderMergedValues*45/45.:spring-bootstrap:test --rerun-taskson 7d44c43, fresh JUnit XML): spring-core 2387, spring-web 930 (6 skipped), spring-ai 776, jpa 138, spring-data 140, base 35, aop 6, security 6, initializr 5 — 0 failures except one spring-aiThreadLeakTrackerleak assertion inSpringBootApplicationMcpToolsetOutsideProjectRootTest, which passed 4/4 when rerun alone (known flake).Main only:
MergedAnnotationAttributes(#673) is not on the release branches.Refs #672