-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial proposal for invokable methods: introduce core concepts
This commit introduces core concepts for CDI invokable methods. An _invokable method_ is a method that: 1. is not `private`; 2. is not a constructor; 3. is declared on a bean class of a managed bean (class-based bean), or inherited from its supertypes; 4. is annotated with an invokable marker annotation, or is declared on a class that is annotated with an invokable marker annotation. An _invokable marker_ annotation is `@Invokable` or any annotation that is meta-annotated `@Invokable`, directly or transitively. That is, application developers may declare invokable methods directly, but that is not the expected common case. It is expected that frameworks will provide their own annotations that will, in addition to their framework-specific nature, also serve as invokable markers. For example, if JAX-RS were to be based on CDI, the `@HttpMethod` annotation would be `@Invokable`. _`Invoker`_ is an indirect way of invoking an invokable method. It is a simple functional interface: ```java interface Invoker<T, R> { R invoke(T instance, Object[] arguments); } ``` Invokers are built using an _`InvokerBuilder`_. They must be stateless and thread-safe, so frameworks can build an invoker for each relevant invokable method once and then reuse it to invoke that method whenever necessary. If an invokable method is intercepted, invocation through an invoker is also intercepted. Portable extensions may inspect invokable methods and obtain an `InvokerBuilder` in an observer of the `ProcessManagedBean` type. The `InvokerBuilder` in this case produces `Invoker` objects directly. iPortable extensions may declare new invokable marker annotations through `BeforeBeanDiscovery`. Build compatible extensions may inspect invokable methods and obtain an `InvokerBuilder` during `@Registration` from the `BeanInfo` object. The `InvokerBuilder` in this case produces `InvokerInfo` objects. `InvokerInfo` is an opaque token that can only be used to materialize an `Invoker` in synthetic components. Build compatible extensions may declare new invokable marker annotations through `MetaAnnotations`.
- Loading branch information
Showing
12 changed files
with
357 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokerInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright (c) 2022 Red Hat and others | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* Apache Software License 2.0 which is available at: | ||
* https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package jakarta.enterprise.inject.build.compatible.spi; | ||
|
||
import jakarta.enterprise.invoke.Invoker; | ||
import jakarta.enterprise.lang.model.declarations.MethodInfo; | ||
|
||
/** | ||
* Opaque token that stands in for an invoker registered using {@link BeanInfo#registerInvoker(MethodInfo)}. | ||
* It can only be used to materialize an {@link Invoker} in a synthetic component; see | ||
* {@link SyntheticBeanBuilder#withParam(String, InvokerInfo) SyntheticBeanBuilder.withParam} or | ||
* {@link SyntheticObserverBuilder#withParam(String, InvokerInfo) SyntheticObserverBuilder.withParam}. | ||
* | ||
* @since 4.1 | ||
*/ | ||
public interface InvokerInfo { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
api/src/main/java/jakarta/enterprise/invoke/Invokable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright (c) 2022 Red Hat and others | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* Apache Software License 2.0 which is available at: | ||
* https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package jakarta.enterprise.invoke; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Marks a method as <em>invokable</em>. For each invokable method belonging to | ||
* a managed bean class, the CDI container allows {@linkplain InvokerBuilder building} | ||
* an {@link Invoker} through which the method can be invoked. | ||
* <p> | ||
* Attempting to mark a private method or a constructor of a managed bean class | ||
* as invokable is a definition error. | ||
* <p> | ||
* Methods that are marked as invokable but do not belong to managed beans are ignored. | ||
* <p> | ||
* When this annotation is present on a class or interface, it marks all non-private | ||
* methods (except constructors) declared in this class as invokable. Note that this | ||
* does not apply to methods declared in superclasses or superinterfaces. | ||
* TODO interfaces are not managed beans and annotations are never inherited from | ||
* interfaces, so maybe just remove the mentions of interfaces altogether? | ||
* <p> | ||
* Note that multiple managed beans may inherit an invokable method from a common | ||
* supertype. In that case, each bean conceptually has its own invokable method | ||
* and for example an invoker obtained for one bean cannot be used to invoke | ||
* the method on the other bean. | ||
* <p> | ||
* This annotation may be used as a meta-annotation. Classes and methods annotated with | ||
* an annotation that is directly or transitively meta-annotated {@code @Invokable} | ||
* are treated as if they were directly annotated {@code @Invokable}. | ||
* | ||
* @since 4.1 | ||
*/ | ||
@Target({ElementType.METHOD, ElementType.TYPE}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Documented | ||
// TODO @Inherited ? | ||
public @interface Invokable { | ||
} |
Oops, something went wrong.