|
| 1 | +[[programmatic_access]] |
| 2 | + |
| 3 | +== Programmatic access to container |
| 4 | + |
| 5 | +CDI 3.0 used to provide a single `BeanManager` object, which allows access to many useful operations. |
| 6 | +In CDI 4.0, this is split into `BeanManagerLite` and `BeanManager`. |
| 7 | + |
| 8 | +`BeanManagerLite` provides access to a subset of `BeanManager` features which can be implemented in more restricted environments; |
| 9 | +It is available in {cdi_lite} environments. |
| 10 | + |
| 11 | +`BeanManager` extends `BeanManagerLite` and provides the remaining features. |
| 12 | +It is available in {cdi_full} environments. |
| 13 | + |
| 14 | +In {cdi_lite} environment, attempting to obtain a `BeanManager` or invoking methods on it results in non-portable behavior. |
| 15 | + |
| 16 | +[[beanmanager]] |
| 17 | + |
| 18 | +=== The `BeanManagerLite` object |
| 19 | + |
| 20 | +The interface `jakarta.enterprise.inject.spi.BeanManagerLite` provides operations for obtaining contextual references for beans, along with many other operations of use to applications. |
| 21 | + |
| 22 | +The container provides a built-in bean with bean type `BeanManagerLite`, scope `@Dependent` and qualifier `@Default`. |
| 23 | +Thus, any bean may obtain an instance of `BeanManagerLite` by injecting it: |
| 24 | + |
| 25 | +[source, java] |
| 26 | +---- |
| 27 | +@Inject BeanManagerLite manager; |
| 28 | +---- |
| 29 | + |
| 30 | +The operations of `BeanManagerLite` may be called at any time during the execution of the application. |
| 31 | + |
| 32 | +[[provider]] |
| 33 | + |
| 34 | +==== Obtaining a reference to the CDI container |
| 35 | + |
| 36 | +Application objects sometimes interact directly with the container via programmatic API call. |
| 37 | +The abstract class `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanManagerLite` as well providing lookup of bean instances. |
| 38 | + |
| 39 | +[source, java] |
| 40 | +---- |
| 41 | +public abstract class CDI<T> implements Instance<T> { |
| 42 | + public static CDI<Object> current() { ... } |
| 43 | + public static void setCDIProvider(CDIProvider provider); |
| 44 | + public abstract BeanManagerLite getBeanManagerLite(); |
| 45 | + public abstract BeanManager getBeanManager(); |
| 46 | +} |
| 47 | +---- |
| 48 | + |
| 49 | +An object may obtain a reference to the current container by calling `CDI.current()`. |
| 50 | +`CDI.getBeanManagerLite()`, as well as other methods on `CDI`, may be called after the application initialization is completed until the application shutdown starts. |
| 51 | +If methods on `CDI` are called at any other time, non-portable behavior results. |
| 52 | + |
| 53 | +`CDI` implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <<dynamic_lookup>>. |
| 54 | +If no qualifier is passed to `CDI.select()` method, the `@Default` qualifier is assumed. |
| 55 | + |
| 56 | +When `CDI.current()` is called, `getCDI()` method is called on `jakarta.enterprise.inject.spi.CDIProvider`. |
| 57 | + |
| 58 | +The `CDIProvider` to use may be set by the application or container using the `setCDIProvider()` method. |
| 59 | +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. |
| 60 | +The order of more than one `CDIProvider` with the same priority is undefined. |
| 61 | +If no provider is available an `IllegalStateException` is thrown. |
| 62 | + |
| 63 | +[source, java] |
| 64 | +---- |
| 65 | +public interface CDIProvider extends Prioritized { |
| 66 | + CDI<Object> getCDI(); |
| 67 | + default int getPriority(); |
| 68 | +} |
| 69 | +---- |
| 70 | + |
| 71 | +* `getPriority()` method is inherited from <<prioritized, `Prioritized` interface>> and returns the priority for the `CDIProvider`. |
| 72 | +If this method is not implemented the default priority `0` is assumed. |
| 73 | + |
| 74 | + |
| 75 | +[[bm_obtain_contextual_reference]] |
| 76 | + |
| 77 | +==== Obtaining a contextual reference for a bean |
| 78 | + |
| 79 | +The method `BeanManagerLite.getReference()` returns a contextual reference for a given bean and bean type, as defined in <<contextual_reference>>. |
| 80 | + |
| 81 | +[source, java] |
| 82 | +---- |
| 83 | +public Object getReference(Bean<?> bean, Type beanType, CreationalContext<?> ctx); |
| 84 | +---- |
| 85 | + |
| 86 | +The first parameter is the `Bean` object representing the bean. |
| 87 | +The second parameter represents a bean type that must be implemented by any client proxy that is returned. |
| 88 | +The third parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. |
| 89 | + |
| 90 | +If the given type is not a bean type of the given bean, an `IllegalArgumentException` is thrown. |
| 91 | + |
| 92 | +[[bm_obtain_injectable_reference]] |
| 93 | + |
| 94 | +==== Obtaining an injectable reference |
| 95 | + |
| 96 | +The method `BeanManagerLite.getInjectableReference()` returns an injectable reference for a given injection point, as defined in <<injectable_reference>>. |
| 97 | + |
| 98 | +[source, java] |
| 99 | +---- |
| 100 | +public Object getInjectableReference(InjectionPoint ij, CreationalContext<?> ctx); |
| 101 | +---- |
| 102 | + |
| 103 | +The first parameter represents the target injection point. |
| 104 | +The second parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. |
| 105 | + |
| 106 | +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`. |
| 107 | + |
| 108 | +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()`. |
| 109 | + |
| 110 | +[[bm_obtain_creationalcontext]] |
| 111 | + |
| 112 | +==== Obtaining a `CreationalContext` |
| 113 | + |
| 114 | +An instance of `CreationalContext` for a certain instance of `Contextual` may be obtained by calling `BeanManagerLite.createCreationalContext()`. |
| 115 | + |
| 116 | +[source, java] |
| 117 | +---- |
| 118 | +public <T> CreationalContext<T> createCreationalContext(Contextual<T> contextual); |
| 119 | +---- |
| 120 | + |
| 121 | +An instance of `CreationalContext` for a non-contextual object may be obtained by passing a null value to `createCreationalContext()`. |
| 122 | + |
| 123 | +[[bm_obtain_bean_by_type]] |
| 124 | + |
| 125 | +==== Obtaining a `Bean` by type |
| 126 | + |
| 127 | +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>>. |
| 128 | + |
| 129 | +[source, java] |
| 130 | +---- |
| 131 | +public Set<Bean<?>> getBeans(Type beanType, Annotation... qualifiers); |
| 132 | +---- |
| 133 | + |
| 134 | +The first parameter is a required bean type. The remaining parameters are required qualifiers. |
| 135 | + |
| 136 | +If no qualifiers are passed to `getBeans()`, the default qualifier `@Default` is assumed. |
| 137 | + |
| 138 | +If the given type represents a type variable, an `IllegalArgumentException` is thrown. |
| 139 | + |
| 140 | +If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. |
| 141 | + |
| 142 | +If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. |
| 143 | + |
| 144 | +[[bm_obtain_bean_by_name]] |
| 145 | + |
| 146 | +==== Obtaining a `Bean` by name |
| 147 | + |
| 148 | +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>>. |
| 149 | + |
| 150 | +[source, java] |
| 151 | +---- |
| 152 | +public Set<Bean<?>> getBeans(String name); |
| 153 | +---- |
| 154 | + |
| 155 | +The parameter is a bean name. |
| 156 | + |
| 157 | +[[bm_resolve_ambiguous_dep]] |
| 158 | + |
| 159 | +==== Resolving an ambiguous dependency |
| 160 | + |
| 161 | +The method `BeanManagerLite.resolve()` applies the ambiguous dependency resolution rules defined in <<unsatisfied_and_ambig_dependencies>> to a set of `Bean` s. |
| 162 | + |
| 163 | +[source, java] |
| 164 | +---- |
| 165 | +public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans); |
| 166 | +---- |
| 167 | + |
| 168 | +If the ambiguous dependency resolution rules fail (as defined in <<unsatisfied_and_ambig_dependencies>>, the container must throw an `AmbiguousResolutionException`. |
| 169 | + |
| 170 | +`BeanManagerLite.resolve()` must return null if: |
| 171 | + |
| 172 | +* null is passed to `resolve()`, or |
| 173 | +* no beans are passed to `resolve()`. |
| 174 | + |
| 175 | +[[bm_fire_event]] |
| 176 | + |
| 177 | +==== Firing an event |
| 178 | + |
| 179 | +The method `BeanManagerLite.getEvent()` returns an instance of `Event` with specified type `java.lang.Object` and specified qualifier `@Default`. |
| 180 | + |
| 181 | +[source, java] |
| 182 | +---- |
| 183 | +Event<Object> getEvent(); |
| 184 | +---- |
| 185 | + |
| 186 | +The returned instance can be used like a standard `Event` as described in <<events>>. |
| 187 | + |
| 188 | +[[bm_observer_method_resolution]] |
| 189 | + |
| 190 | +==== Observer method resolution |
| 191 | + |
| 192 | +The method `BeanManagerLite.resolveObserverMethods()` resolves observer methods for an event according to the rules of observer resolution defined in <<observer_resolution>>. |
| 193 | + |
| 194 | +[source, java] |
| 195 | +---- |
| 196 | +public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... qualifiers); |
| 197 | +---- |
| 198 | + |
| 199 | +The first parameter of `resolveObserverMethods()` is the event object. |
| 200 | +The remaining parameters are event qualifiers. |
| 201 | + |
| 202 | +If the runtime type of the event object contains a type variable, an `IllegalArgumentException` is thrown. |
| 203 | + |
| 204 | +If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. |
| 205 | + |
| 206 | +If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. |
| 207 | + |
| 208 | +[[bm_interceptor_resolution]] |
| 209 | + |
| 210 | +==== Interceptor resolution |
| 211 | + |
| 212 | +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>>. |
| 213 | + |
| 214 | +[source, java] |
| 215 | +---- |
| 216 | +List<Interceptor<?>> resolveInterceptors(InterceptionType type, |
| 217 | + Annotation... interceptorBindings); |
| 218 | +---- |
| 219 | + |
| 220 | +If two instances of the same non repeating interceptor binding type are given, an `IllegalArgumentException` is thrown. |
| 221 | + |
| 222 | +If no interceptor binding type instance is given, an `IllegalArgumentException` is thrown. |
| 223 | + |
| 224 | +If an instance of an annotation that is not an interceptor binding type is given, an `IllegalArgumentException` is thrown. |
| 225 | + |
| 226 | +[[bm_determining_annotation]] |
| 227 | + |
| 228 | +==== Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type |
| 229 | + |
| 230 | +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. |
| 231 | + |
| 232 | +[source, java] |
| 233 | +---- |
| 234 | +public boolean isScope(Class<? extends Annotation> annotationType); |
| 235 | +public boolean isNormalScope(Class<? extends Annotation> scopeType); |
| 236 | +
|
| 237 | +public boolean isQualifier(Class<? extends Annotation> annotationType); |
| 238 | +public boolean isInterceptorBinding(Class<? extends Annotation> annotationType); |
| 239 | +public boolean isStereotype(Class<? extends Annotation> annotationType); |
| 240 | +---- |
| 241 | + |
| 242 | +[[bm_obtain_active_context]] |
| 243 | + |
| 244 | +==== Obtaining the active `Context` for a scope |
| 245 | + |
| 246 | +The method `BeanManagerLite.getContext()` retrieves an active context object associated with the given scope, as defined in <<active_context>>. |
| 247 | + |
| 248 | +[source, java] |
| 249 | +---- |
| 250 | +public Context getContext(Class<? extends Annotation> scopeType); |
| 251 | +---- |
| 252 | + |
| 253 | +[[bm_obtain_instance]] |
| 254 | + |
| 255 | +==== Obtain an `Instance` |
| 256 | + |
| 257 | +The method `BeanManagerLite.createInstance()` returns an `Instance<Object>` to request bean instances programmatically as described in <<dynamic_lookup>>. |
| 258 | + |
| 259 | +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>>. |
| 260 | + |
| 261 | +[source, java] |
| 262 | +---- |
| 263 | +Instance<Object> createInstance(); |
| 264 | +---- |
| 265 | + |
| 266 | +Instances of dependent scoped beans obtained with this `Instance` object must be explicitly released by calling `Instance.destroy()` method. |
| 267 | + |
| 268 | +If no qualifier is passed to `Instance.select()` method, the `@Default` qualifier is assumed. |
0 commit comments