Interface Invoker<T,R>
- Type Parameters:
T
- type of the target instanceR
- return type of the method
static
.
Whenever a direct invocation of a method is a business method invocation, an indirect invocation of that method through an invoker is also a business method invocation.
Invoker implementations must be thread-safe. It is possible to use a single invoker instance to perform multiple independent invocations of the target method, possibly on different instances and with different arguments.
Obtaining an invoker
The CDI container allows building an invoker for non-private methods declared on a managed bean class or inherited from a supertype. Attempting to build an invoker for a private method or a constructor of a managed bean class leads to a deployment problem. Attempting to build an invoker for a method of a class that is not a managed bean class or that is an interceptor or decorator class leads to a deployment problem.Multiple managed beans may inherit a method from a common supertype. In that case, each bean conceptually has its own method and an invoker obtained for one bean may not be used to invoke the method on the other bean.
Using the InvokerBuilder
is the only way to obtain an invoker. An InvokerBuilder
can only be obtained in CDI portable extensions and build compatible extensions.
Example
To illustrate how invokers work, let's take a look at an example. Say that the following bean exists and has a method that you want to invoke indirectly:@Dependent class MyService { String hello(String name) { return "Hello " + name + "!"; } }When you obtain an
InvokerBuilder
for the hello()
method, you can
immediately build a direct invoker. In a portable extension, this results in an invoker:
InvokerBuilder<Invoker<MyService, String>> builder = ...; Invoker<MyService, String> invoker = builder.build();In a build compatible extension, this results in an opaque token that later materializes as an invoker:
InvokerBuilder<InvokerInfo> builder = ...; InvokerInfo invoker = builder.build();To call the
hello()
method through this invoker, call
invoker.invoke(myService, new Object[] {"world"})
.
The return value is "Hello world!"
.
An implementation of the direct invoker above is equivalent to the following class:
class TheInvoker implements Invoker<MyService, String> { String invoke(MyService instance, Object[] arguments) { return instance.hello((String) arguments[0]); } }
- Since:
- 4.1
- See Also:
-
Method Summary
-
Method Details
-
invoke
Invokes the target method of this invoker on giveninstance
, passing givenarguments
. If the target method isstatic
, theinstance
is ignored; by convention, it should benull
. If the target method returns normally, this method returns its return value, unless the target method is declaredvoid
, in which case this method returnsnull
. If the target method throws an exception, this method rethrows it directly.If some parameter of the target method declares a primitive type, the corresponding element of the
arguments
array must be of the corresponding wrapper type. No type conversions are performed, so if the parameter is declaredint
, the argument must be anInteger
and may not beShort
orLong
. If the argument isnull
, the default value of the primitive type is used. Note that this does not apply to arrays of primitive types; if a parameter is declaredint[]
, the argument must beint[]
and may not beInteger[]
.If the target method is not
static
andinstance
isnull
, aNullPointerException
is thrown. If the target method is notstatic
and theinstance
is not assignable to the class of the bean to which the method belongs, aClassCastException
is thrown.If the target method declares no parameter,
arguments
are ignored. If the target method declares any parameter andarguments
isnull
,NullPointerException
is thrown. If thearguments
array has fewer elements than the number of parameters of the target method,ArrayIndexOutOfBoundsException
is thrown. If thearguments
array has more elements than the number of parameters of the target method, the excess elements are ignored. If some of thearguments
is not assignable to the declared type of the corresponding parameter of the target method,ClassCastException
is thrown. TODO the previous 2 paragraphs refer to "assignability", which needs to be defined somewhere! TODO when the `InvokerBuilder` applies transformations, some of the requirements above are no longer strictly necessary, should reflect that in this text somehow (it is already mentioned in `InvokerBuilder`, but that likely isn't enough)- Parameters:
instance
- the instance on which the target method is to be invoked, may only benull
if the method isstatic
arguments
- arguments to be supplied to the target method, may only benull
if the method declares no parameter- Returns:
- return value of the target method, or
null
if the method is declaredvoid
-