Currently, a new InvocableHandlerMethod is created on each controller request, and in turn, creates a new HandlerMethodArgumentResolverComposite and new argumentResolverCache which makes each request calculate the argument resolver of this method.

This PR changes this behavior and caches the InvocableHandlerMethod by its HandlerMethod, which should reduce the number of resolvers lookups, which shouldn't change between invocations.

Closes https://github.com/spring-projects/spring-framework/issues/29951

Comment From: ohadgur

Not sure why org.springframework.web.reactive.function.MultipartRouterFunctionIntegrationTests.proxy failed because of it, and I can't reproduce locally..

Comment From: ohadgur

hi @rstoyanchev , I just merged from main to re-run the build, can you please check? thanks

Comment From: rstoyanchev

To elaborate further, we don't want to re-use a cached HandlerMethod when the bean (controller) instance is not the same. The cache is based on HandlerMethod#equals, which calls bean#equals, and if the controller implemented it, it wouldn't be a same instance check which what we want. We could create a cache key specific for this, but then if some controllers are prototype beans, it would make the cache grow.

In short, solving this would require more extensive changes, but I'm not sure there is sufficient gain to justify it.

Comment From: ohadgur

@rstoyanchev thanks for taking the time to explain. The reason I started this issue is that this code path (especially the argument resolving) comes up in our profiling with ~2-3% of the total CPU usage, which isn't negligible. Attaching a screenshot of the flamegraph. Spring reactive ControllerMethodResolver - introduce InvocableHandlerMethod cache Do you think a cache key such as (bean type, method/method name), be good enough?