Class ExecutableMethodELExecutor
- All Implemented Interfaces:
io.micronaut.core.order.Ordered, ELMethodExecutor
ELMethodExecutor invoking a method of a bean through the executable metadata its bean definition
carries, the metadata Micronaut generates for every method annotated with
io.micronaut.context.annotation.Executable, directly or through an annotation that is itself
meta-annotated with it.
A bean introspection and an executable method are two independent descriptions of a type, and a great
many beans carry the second without the first: anything AOP-advised, anything a framework marks executable
for its own dispatch. This executor makes such a method reachable from an expression without the type also
having to be annotated @Introspected.
The class is both an ELMethodExecutor and an ELResolver because the two execution paths of
this project reach a method differently: an expression parsed at runtime resolves it through the
ELMethodExecutor services, while an expression compiled at compilation time dispatches through the
resolver chain of its context, ELResolution.invoke calling ELContext.getELResolver().invoke.
One implementation answers both, so a method resolves the same way whichever path an expression took.
The executor is registered in META-INF/services/io.micronaut.el.ELMethodExecutor, so it is
available to every expression parsed at runtime with no wiring at all. Registered that way it is constructed
with the no-argument constructor and has no bean context of its own, so it reads one from the
ELContext of each call, which an application registers once:
context.putContext(BeanDefinitionRegistry.class, beanContext);
BeanContext.class works as the key as well. A context that carries neither is not one this
executor can read, so it declines and the rest of the chain resolves the method as it did before. Reading the
registry from the context rather than from a static holder is what lets an application that runs more than
one bean context resolve a method in the context the expression is evaluated for; the
ExecutableMethodELExecutor(BeanDefinitionRegistry) constructor binds one directly, for the resolver
chain and for an application registering the executor programmatically.
The executor only invokes: the properties stay with the rest of the chain. A base whose class is not a
bean of the context has no definition, so the executor declines and the reflective one gets its chance. The
runtime class of an intercepted instance is the generated proxy, whose definition is a
ProxyBeanDefinition; the executor reads the executable methods of the target definition, so the
method that is found is the one the author wrote.
Like IntrospectionELResolver, the executor reads compiled metadata rather than reflection, so it
works under a GraalVM native image without any registration.
- Since:
- 1.1
- Author:
- Denis Stepanov
-
Field Summary
Fields inherited from interface io.micronaut.core.order.Ordered
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE -
Constructor Summary
ConstructorsConstructorDescriptionCreates the executor reading, on every call, the registry registered in theELContextthe expression is evaluated with, under the keyBeanDefinitionRegistry.classorBeanContext.class.ExecutableMethodELExecutor(io.micronaut.context.BeanDefinitionRegistry registry) Creates the executor reading the definitions of a registry. -
Method Summary
Modifier and TypeMethodDescription@Nullable Class<?> getCommonPropertyType(jakarta.el.ELContext context, @Nullable Object base) intgetOrder()Returns the executor order.@Nullable Class<?> @Nullable Object@Nullable Objectinvoke(jakarta.el.ELContext context, @Nullable Object base, @Nullable Object method, Class<?> @Nullable [] paramTypes, Object @Nullable [] params) booleanisReadOnly(jakarta.el.ELContext context, @Nullable Object base, @Nullable Object property) @Nullable ELMethodresolve(jakarta.el.ELContext context, @Nullable Object base, @Nullable Object method, io.micronaut.core.type.Argument<?> @Nullable [] argumentTypes, Object @Nullable [] arguments) Resolves an instance or static method, or a constructor represented by<init>.voidsetValue(jakarta.el.ELContext context, @Nullable Object base, @Nullable Object property, @Nullable Object value) Methods inherited from class jakarta.el.ELResolver
convertToTypeMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface ELMethodExecutor
isReflective, resolveFunction
-
Constructor Details
-
ExecutableMethodELExecutor
public ExecutableMethodELExecutor()Creates the executor reading, on every call, the registry registered in theELContextthe expression is evaluated with, under the keyBeanDefinitionRegistry.classorBeanContext.class.This is the constructor the service loader uses. An expression evaluated with a context that carries no registry resolves the way it did before this executor existed.
-
ExecutableMethodELExecutor
public ExecutableMethodELExecutor(io.micronaut.context.BeanDefinitionRegistry registry) Creates the executor reading the definitions of a registry.A
io.micronaut.context.BeanContextis one, and is what an application usually has. The narrower type is what this executor actually needs: it reads the executable metadata of a definition and invokes the method on the instance the expression produced, so it never looks a bean up, creates one, or touches the lifecycle of the context.- Parameters:
registry- The registry whose definitions carry the executable methods
-
-
Method Details
-
getOrder
public int getOrder()Description copied from interface:ELMethodExecutorReturns the executor order. Lower values run first, following the MicronautOrderedcontract, so direct/generated implementations can take precedence over a general fallback such as reflection.- Specified by:
getOrderin interfaceELMethodExecutor- Specified by:
getOrderin interfaceio.micronaut.core.order.Ordered- Returns:
- The order, zero by default
-
invoke
-
resolve
public @Nullable ELMethod resolve(jakarta.el.ELContext context, @Nullable Object base, @Nullable Object method, io.micronaut.core.type.Argument<?> @Nullable [] argumentTypes, Object @Nullable [] arguments) Description copied from interface:ELMethodExecutorResolves an instance or static method, or a constructor represented by<init>.- Specified by:
resolvein interfaceELMethodExecutor- Parameters:
context- The EL contextbase- The instance, or anELClassfor a static method or constructormethod- The method nameargumentTypes- The parameter types supplied when the method expression was created, ornullarguments- The evaluated arguments, ornull- Returns:
- The resolved method, or
nullwhen this executor does not handle it
-
getValue
-
getType
-
setValue
-
isReadOnly
-
getCommonPropertyType
-