-
Notifications
You must be signed in to change notification settings - Fork 81
Method invokers #460
Copy link
Copy link
Closed
Labels
spec-featureAn issue requesting an addition specificationAn issue requesting an addition specification
Milestone
Description
(copied from CDI.Next doc, as there was no issue yet to track this)
Currently CDI does not have a concept of a bean method that can be executed from another bean with parameter binding.
Such a concept is used in other specs, such as JAX-RS, where resource methods are executed at runtime with the need to bind their parameters, and provide the support for interceptors and other CDI features.
The CDI spec should add API for such a feature, so other specs do not need to define a custom solution.
The following should be possible:
- Obtain a reference to executable method with all metadata, including annotations on method and on fields
- Execute an executable method on a bean instance
- Obtain executable method metadata in interceptors (to analyze annotations using reflection-less approach)
- Create a parameter binder, that would support a specific annotation on a parameter (basically a parameter qualifier)
Pseudocode:
Let’s consider the following bean:
@RequestScoped
@Path("/greet")
public class Resource {
@GET
String helloWorld(@HeaderParam("HEADER") String header) {
}
}@Qualifier
@Target(ElementType.PARAMETER)
public @interface HeaderParam {
String value();
}Now we could create a parameter binder:
@Singleton
@Binder(HeaderParam.class)
public class HeaderParamBinder implements ParamBinder {
// HttpHeaders is a request scoped bean
private final HttpHeaders headers;
private final Converter converter;
@Inject
HeaderParamBinder(HttpHeaders headers, Converter converter) {
this.headers = headers;
this.converter = converter;
}
public <T> T bind(HeaderParam annotation, GenericType<T> type) {
return converter.convert(headers.getRequestHeader(annotation.value()), type);
}
}And the execution of this method would be something like:
@MethodHandler(Path.class)
public class JaxRsExecutor implements ExecMethodHandler<Object, Object> {
private final ParameterBinder binder;
private final Container container;
@Inject
JaxRsExecutor(ArgumentBinder binder) {
this.binder = binder;
}
@Override
public void processMethod(ExecutableMethod<Object, Object> method) {
// process registration with web server
}
private void executeMethod(ExecutableMethod<Object, Object> method) {
// start request scope
Object beanInstance = container.select(method.getDeclaringType()).get();
method.invoke(beanInstance, binder.bind(method));
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
spec-featureAn issue requesting an addition specificationAn issue requesting an addition specification