Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SpEL support for registered MethodHandles #30045

Merged
merged 1 commit into from
May 5, 2023

Conversation

simonbasle
Copy link
Contributor

@simonbasle simonbasle commented Feb 27, 2023

This commit adds support for MethodHandles in SpEL, using the same
syntax as user-defined functions (which also covers reflective Methods).

The most benefit is expected with handles that capture a static method
with no arguments, or with fully bound handles (where all the arguments
have been bound, including a target instance as first bound argument
if necessary). Partially bound MethodHandle should also be supported.

A best effort approach is taken to detect varargs as there is no API
support to determine if an argument is a vararg or an explicit array,
unlike with Method. Argument conversions are also applied. Finally,
array repacking is not always necessary with varargs so it is only
performed when the vararg is the sole argument to the invoked method.

Closes gh-27099
Closes gh-30045

@simonbasle simonbasle self-assigned this Feb 27, 2023
@simonbasle simonbasle added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Feb 27, 2023
@simonbasle simonbasle added this to the 6.0.x milestone Feb 27, 2023
@simonbasle simonbasle marked this pull request as ready for review February 27, 2023 19:08
for (int i = 0; i < arguments.length; i++) {
Class<?> argumentClass = methodHandleArgumentTypes.parameterType(i);
ResolvableType resolvableType = ResolvableType.forClass(argumentClass);
TypeDescriptor targetType = new TypeDescriptor(resolvableType, argumentClass, null);
Copy link
Contributor Author

@simonbasle simonbasle Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here the subtle difference compared to the older convertAllMethodArguments higher in the source file is that we get TypeDescriptor out of a raw Class only (vs a MethodParam obtained via reflection with MethodParameter.forExecutable)

@jhoeller jhoeller modified the milestones: 6.0.x, 6.1.0-M1 Mar 7, 2023
@simonbasle
Copy link
Contributor Author

@ericbottard if you're still interested, feel free to test that out and validate this covers your original use case 😉

@ericbottard
Copy link
Member

A quick glance at the docs and test tells me this would have been useful. We went with another route (and that leaked in the exposed API sadly), but glad to see this got supported eventually. Thanks!

This commit adds support for MethodHandles in SpEL, using the same
syntax as user-defined functions (which also covers reflective Methods).

The most benefit is expected with handles that capture a static method
with no arguments, or with fully bound handles (where all the arguments
have been bound, including a target instance as first bound argument
if necessary). Partially bound MethodHandle should also be supported.

A best effort approach is taken to detect varargs as there is no API
support to determine if an argument is a vararg or an explicit array,
unlike with Method. Argument conversions are also applied. Finally,
array repacking is not always necessary with varargs so it is only
performed when the vararg is the sole argument to the invoked method.

See spring-projectsgh-27099
Closes spring-projectsgh-30045
@simonbasle simonbasle force-pushed the 27099-spelMethodHandle branch from 203ab5f to 88a5167 Compare May 5, 2023 13:58
@simonbasle
Copy link
Contributor Author

Now rebased on top of latest reference doc changes (Antora) and squashed into a single commit.

@simonbasle simonbasle merged commit 906c54f into spring-projects:main May 5, 2023
@simonbasle simonbasle deleted the 27099-spelMethodHandle branch May 5, 2023 14:18
@fanthos
Copy link

fanthos commented May 6, 2023

Is it possible to backport this feature to 5.x? Java 17 is not ready in many environments.

@simonbasle
Copy link
Contributor Author

simonbasle commented May 9, 2023

Is it possible to backport this feature to 5.x? Java 17 is not ready in many environments.

@fanthos this is very unlikely. We don't backport purely new features to the 5.3.x line, and now that the work has started on 6.1.x, we tend to avoid doing so in 6.0.x as well.

edit: got confused, MethodHandle is from Java 8. but the above point still stands

jhoeller added a commit that referenced this pull request May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SpEL FunctionReference could support MethodHandle
4 participants