-
Notifications
You must be signed in to change notification settings - Fork 77
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
cdi-468 Split Spec doc to introduce CDI Lite #470
Changes from 1 commit
58177d9
0aec646
893141b
a45fbe3
af8fc82
2717c29
ac06dcd
e29216e
b1638a2
d8d2885
864e1b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
[[programmatic_access]] | ||
|
||
== Programmatic access to container | ||
|
||
CDI 3.0 used to provide a single `BeanManager` object, which allows access to many useful operations. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not only true for CDI 3.0 though. I would say: The CDI version prior to 4.0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you could suggest a way how to phrase this without the historical reference, that would be best. I admit I didn't give it much thought, I'll think about it again. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
In CDI 4.0, this is split into `BeanManagerLite` and `BeanManager`. | ||
|
||
`BeanManagerLite` provides access to a subset of `BeanManager` features which can be implemented in more restricted environments; | ||
It is available in {cdi_lite} environments. | ||
|
||
`BeanManager` extends `BeanManagerLite` and provides the remaining features. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the remaining features -> more capabilities |
||
It is available in {cdi_full} environments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. {cdi_full} environments environments -> a {cdi_full} environment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The plural form here is correct because there are two CDI Full environments - SE and EE There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll try to rephrase this paragraph today, there are too many comments so I clearly have to do a better job :-) |
||
|
||
In {cdi_lite} environment, attempting to obtain a `BeanManager` or invoking methods on it results in non-portable behavior. | ||
|
||
[[beanmanager]] | ||
|
||
=== The `BeanManagerLite` object | ||
|
||
The interface `jakarta.enterprise.inject.spi.BeanManagerLite` provides operations for obtaining contextual references for beans, along with many other operations of use to applications. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can BeanManagerLite be looked up via jndi lookup at runtime? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we should avoid references to JNDI, as well as other Jakarta EE concepts, in Lite. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (In fact, I briefly thought we should move that JNDI thing to the EE section. I don't know why it's present in "Core CDI", it's clearly EE only and for example can't be used in SE.) EDIT: I just realized you can have JNDI in SE. I'd still like to avoid references to JNDI in Lite. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I raised this question at some earlier comment on the BM Lite PR as well. Technically speaking you can get the BML via JNDI simply because you can get ordinary BM (which extends BML). That being said, IMO we don't want any specific notion of Lite supporting JNDI in any way. |
||
|
||
The container provides a built-in bean with bean type `BeanManagerLite`, scope `@Dependent` and qualifier `@Default`. | ||
Thus, any bean may obtain an instance of `BeanManagerLite` by injecting it: | ||
|
||
[source, java] | ||
---- | ||
@Inject BeanManagerLite manager; | ||
---- | ||
|
||
The operations of `BeanManagerLite` may be called at any time during the execution of the application. | ||
|
||
[[provider]] | ||
|
||
==== Obtaining a reference to the CDI container | ||
|
||
Application objects sometimes interact directly with the container via programmatic API call. | ||
The abstract class `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanManagerLite` as well providing lookup of bean instances. | ||
|
||
[source, java] | ||
---- | ||
public abstract class CDI<T> implements Instance<T> { | ||
public static CDI<Object> current() { ... } | ||
public static void setCDIProvider(CDIProvider provider); | ||
public abstract BeanManagerLite getBeanManagerLite(); | ||
public abstract BeanManager getBeanManager(); | ||
} | ||
---- | ||
|
||
An object may obtain a reference to the current container by calling `CDI.current()`. | ||
`CDI.getBeanManagerLite()`, as well as other methods on `CDI`, may be called after the application initialization is completed until the application shutdown starts. | ||
If methods on `CDI` are called at any other time, non-portable behavior results. | ||
|
||
`CDI` implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <<dynamic_lookup>>. | ||
If no qualifier is passed to `CDI.select()` method, the `@Default` qualifier is assumed. | ||
|
||
When `CDI.current()` is called, `getCDI()` method is called on `jakarta.enterprise.inject.spi.CDIProvider`. | ||
|
||
The `CDIProvider` to use may be set by the application or container using the `setCDIProvider()` method. | ||
If the `setCDIProvider()` has not been called, the service provider with highest priority of the service `jakarta.enterprise.inject.spi.CDIProvider` declared in META-INF/services is used. | ||
The order of more than one `CDIProvider` with the same priority is undefined. | ||
If no provider is available an `IllegalStateException` is thrown. | ||
|
||
[source, java] | ||
---- | ||
public interface CDIProvider extends Prioritized { | ||
CDI<Object> getCDI(); | ||
default int getPriority(); | ||
} | ||
---- | ||
|
||
* `getPriority()` method is inherited from <<prioritized, `Prioritized` interface>> and returns the priority for the `CDIProvider`. | ||
If this method is not implemented the default priority `0` is assumed. | ||
|
||
|
||
[[bm_obtain_contextual_reference]] | ||
|
||
==== Obtaining a contextual reference for a bean | ||
|
||
The method `BeanManagerLite.getReference()` returns a contextual reference for a given bean and bean type, as defined in <<contextual_reference>>. | ||
|
||
[source, java] | ||
---- | ||
public Object getReference(Bean<?> bean, Type beanType, CreationalContext<?> ctx); | ||
---- | ||
|
||
The first parameter is the `Bean` object representing the bean. | ||
The second parameter represents a bean type that must be implemented by any client proxy that is returned. | ||
The third parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. | ||
|
||
If the given type is not a bean type of the given bean, an `IllegalArgumentException` is thrown. | ||
|
||
[[bm_obtain_injectable_reference]] | ||
|
||
==== Obtaining an injectable reference | ||
|
||
The method `BeanManagerLite.getInjectableReference()` returns an injectable reference for a given injection point, as defined in <<injectable_reference>>. | ||
|
||
[source, java] | ||
---- | ||
public Object getInjectableReference(InjectionPoint ij, CreationalContext<?> ctx); | ||
---- | ||
|
||
The first parameter represents the target injection point. | ||
The second parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. | ||
|
||
If typesafe resolution results in an unsatisfied dependency, the container must throw an `UnsatisfiedResolutionException`. If typesafe resolution results in an unresolvable ambiguous dependency, the container must throw an `AmbiguousResolutionException`. | ||
|
||
Implementations of `Bean` usually maintain a reference to an instance of `BeanManagerLite`. When the `Bean` implementation performs dependency injection, it must obtain the contextual instances to inject by calling `BeanManagerLite.getInjectableReference()`, passing an instance of `InjectionPoint` that represents the injection point and the instance of `CreationalContext` that was passed to `Bean.create()`. | ||
|
||
[[bm_obtain_creationalcontext]] | ||
|
||
==== Obtaining a `CreationalContext` | ||
|
||
An instance of `CreationalContext` for a certain instance of `Contextual` may be obtained by calling `BeanManagerLite.createCreationalContext()`. | ||
|
||
[source, java] | ||
---- | ||
public <T> CreationalContext<T> createCreationalContext(Contextual<T> contextual); | ||
---- | ||
|
||
An instance of `CreationalContext` for a non-contextual object may be obtained by passing a null value to `createCreationalContext()`. | ||
|
||
[[bm_obtain_bean_by_type]] | ||
|
||
==== Obtaining a `Bean` by type | ||
|
||
The method `BeanManagerLite.getBeans()` returns the set of beans which have the given required type and qualifiers and are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules for candidates of typesafe resolution defined in <<performing_typesafe_resolution>>. | ||
|
||
[source, java] | ||
---- | ||
public Set<Bean<?>> getBeans(Type beanType, Annotation... qualifiers); | ||
---- | ||
|
||
The first parameter is a required bean type. The remaining parameters are required qualifiers. | ||
|
||
If no qualifiers are passed to `getBeans()`, the default qualifier `@Default` is assumed. | ||
|
||
If the given type represents a type variable, an `IllegalArgumentException` is thrown. | ||
|
||
If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. | ||
|
||
If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. | ||
|
||
[[bm_obtain_bean_by_name]] | ||
|
||
==== Obtaining a `Bean` by name | ||
|
||
The method `BeanManagerLite.getBeans()` which accepts a string returns the set of beans which have the given bean name and are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules of name resolution defined in <<name_resolution>>. | ||
|
||
[source, java] | ||
---- | ||
public Set<Bean<?>> getBeans(String name); | ||
---- | ||
|
||
The parameter is a bean name. | ||
|
||
[[bm_resolve_ambiguous_dep]] | ||
|
||
==== Resolving an ambiguous dependency | ||
|
||
The method `BeanManagerLite.resolve()` applies the ambiguous dependency resolution rules defined in <<unsatisfied_and_ambig_dependencies>> to a set of `Bean` s. | ||
|
||
[source, java] | ||
---- | ||
public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans); | ||
---- | ||
|
||
If the ambiguous dependency resolution rules fail (as defined in <<unsatisfied_and_ambig_dependencies>>, the container must throw an `AmbiguousResolutionException`. | ||
|
||
`BeanManagerLite.resolve()` must return null if: | ||
|
||
* null is passed to `resolve()`, or | ||
* no beans are passed to `resolve()`. | ||
|
||
[[bm_fire_event]] | ||
|
||
==== Firing an event | ||
|
||
The method `BeanManagerLite.getEvent()` returns an instance of `Event` with specified type `java.lang.Object` and specified qualifier `@Default`. | ||
|
||
[source, java] | ||
---- | ||
Event<Object> getEvent(); | ||
---- | ||
|
||
The returned instance can be used like a standard `Event` as described in <<events>>. | ||
|
||
[[bm_observer_method_resolution]] | ||
|
||
==== Observer method resolution | ||
|
||
The method `BeanManagerLite.resolveObserverMethods()` resolves observer methods for an event according to the rules of observer resolution defined in <<observer_resolution>>. | ||
|
||
[source, java] | ||
---- | ||
public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... qualifiers); | ||
---- | ||
|
||
The first parameter of `resolveObserverMethods()` is the event object. | ||
The remaining parameters are event qualifiers. | ||
|
||
If the runtime type of the event object contains a type variable, an `IllegalArgumentException` is thrown. | ||
|
||
If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. | ||
|
||
If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. | ||
|
||
[[bm_interceptor_resolution]] | ||
|
||
==== Interceptor resolution | ||
|
||
The method `BeanManagerLite.resolveInterceptors()` returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the `BeanManagerLite` was injected, as defined in <<interceptor_resolution>>. | ||
|
||
[source, java] | ||
---- | ||
List<Interceptor<?>> resolveInterceptors(InterceptionType type, | ||
Annotation... interceptorBindings); | ||
---- | ||
|
||
If two instances of the same non repeating interceptor binding type are given, an `IllegalArgumentException` is thrown. | ||
|
||
If no interceptor binding type instance is given, an `IllegalArgumentException` is thrown. | ||
|
||
If an instance of an annotation that is not an interceptor binding type is given, an `IllegalArgumentException` is thrown. | ||
|
||
[[bm_determining_annotation]] | ||
|
||
==== Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type | ||
|
||
An application may test an annotation to determine if it is a qualifier type, scope type, stereotype or interceptor binding type, or determine if a scope type is a normal scope. | ||
|
||
[source, java] | ||
---- | ||
public boolean isScope(Class<? extends Annotation> annotationType); | ||
public boolean isNormalScope(Class<? extends Annotation> scopeType); | ||
|
||
public boolean isQualifier(Class<? extends Annotation> annotationType); | ||
public boolean isInterceptorBinding(Class<? extends Annotation> annotationType); | ||
public boolean isStereotype(Class<? extends Annotation> annotationType); | ||
---- | ||
|
||
[[bm_obtain_active_context]] | ||
|
||
==== Obtaining the active `Context` for a scope | ||
|
||
The method `BeanManagerLite.getContext()` retrieves an active context object associated with the given scope, as defined in <<active_context>>. | ||
|
||
[source, java] | ||
---- | ||
public Context getContext(Class<? extends Annotation> scopeType); | ||
---- | ||
|
||
[[bm_obtain_instance]] | ||
|
||
==== Obtain an `Instance` | ||
|
||
The method `BeanManagerLite.createInstance()` returns an `Instance<Object>` to request bean instances programmatically as described in <<dynamic_lookup>>. | ||
|
||
The returned `Instance` object can only access instances of beans that are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules defined in <<typesafe_resolution>>. | ||
|
||
[source, java] | ||
---- | ||
Instance<Object> createInstance(); | ||
---- | ||
|
||
Instances of dependent scoped beans obtained with this `Instance` object must be explicitly released by calling `Instance.destroy()` method. | ||
|
||
If no qualifier is passed to `Instance.select()` method, the `@Default` qualifier is assumed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to define cdi full and cdi liter concept first in this chapter and then refer to it.