diff --git a/api/src/main/java/jakarta/enterprise/inject/spi/BeanContainer.java b/api/src/main/java/jakarta/enterprise/inject/spi/BeanContainer.java new file mode 100644 index 00000000..2471aaae --- /dev/null +++ b/api/src/main/java/jakarta/enterprise/inject/spi/BeanContainer.java @@ -0,0 +1,264 @@ +package jakarta.enterprise.inject.spi; + +import jakarta.enterprise.context.ContextNotActiveException; +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.context.spi.Context; +import jakarta.enterprise.context.spi.Contextual; +import jakarta.enterprise.context.spi.CreationalContext; +import jakarta.enterprise.event.Event; +import jakarta.enterprise.inject.AmbiguousResolutionException; +import jakarta.enterprise.inject.Default; +import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.inject.Stereotype; +import jakarta.enterprise.inject.UnsatisfiedResolutionException; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; + +/** + *

+ * {@link BeanContainer} is a superclass of {@link BeanManager} containing capabilities that are portable across + * all CDI environments. + *

+ * + *

+ * Provides operations for obtaining contextual references for beans, along with many other operations of use to + * CDI applications. + *

+ * + *

+ * Any bean may obtain an instance of BeanContainer by injecting it: + *

+ * + *
+ * @Inject
+ * BeanContainer manager;
+ * 
+ * + * @author Matej Novotny + */ +public interface BeanContainer { + + /** + *

+ * Obtains a contextual reference for a certain {@linkplain Bean bean} and a certain bean type of the bean. + *

+ * + * @param bean the {@link Bean} object representing the bean + * @param beanType a bean type that must be implemented by any client proxy that is returned + * @param ctx a {@link CreationalContext} that may be used to destroy any object with scope + * {@link Dependent} that is created + * @return a contextual reference representing the bean + * @throws IllegalArgumentException if the given type is not a bean type of the given bean + * @throws IllegalStateException if called during application initialization, before the {@link AfterDeploymentValidation} + * event is fired. + */ + Object getReference(Bean bean, Type beanType, CreationalContext ctx); + + /** + *

+ * Obtains an injectable reference for a certain {@linkplain InjectionPoint injection point}. + *

+ * + * @param ij the target injection point + * @param ctx a {@link CreationalContext} that may be used to destroy any object with scope + * {@link Dependent} that is created + * @return the injectable reference + * @throws UnsatisfiedResolutionException if typesafe resolution results in an unsatisfied dependency + * @throws AmbiguousResolutionException typesafe resolution results in an unresolvable ambiguous dependency + * @throws IllegalStateException if called during application initialization, before the {@link AfterDeploymentValidation} + * event is fired. + */ + Object getInjectableReference(InjectionPoint ij, CreationalContext ctx); + + /** + * Obtain an instance of a {@link CreationalContext} for the given + * {@linkplain Contextual contextual type}, or for a non-contextual object. + * + * @param type of the instance + * @param contextual the {@link Contextual}, or a null value in the case of a non-contextual + * object + * @return the new {@link CreationalContext} + */ + CreationalContext createCreationalContext(Contextual contextual); + + /** + * Return 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 BeanManager/BeanContainer was injected or, + * in the Jakarta EE environment, the Jakarta EE component from whose JNDI environment namespace the + * BeanManager/BeanContainer was obtained, according to the rules of typesafe resolution. + * If no qualifiers are given, the {@linkplain Default default qualifier} is assumed. + *

+ * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, + * this method will only return beans discovered by the container before the {@link AfterBeanDiscovery} event is fired. + * + * @param beanType the required bean type + * @param qualifiers the required qualifiers + * @return the resulting set of {@linkplain Bean beans} + * @throws IllegalArgumentException if the given type represents a type variable + * @throws IllegalArgumentException if two instances of the same non repeating qualifier type are given + * @throws IllegalArgumentException if an instance of an annotation that is not a qualifier type is given + * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} + * event is fired. + */ + Set> getBeans(Type beanType, Annotation... qualifiers); + + /** + * Return the set of beans which have the given EL name and are available for injection in the module or library containing + * the class into which the BeanManager/BeanContainer was injected or, in the Jakarta EE + * environment, the Jakarta EE component from whose JNDI environment namespace the + * BeanManager/BeanContainer was obtained, according to the rules of EL name resolution. + *

+ * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, + * this method will only return beans discovered by the container before the {@link AfterBeanDiscovery} event is fired. + * + * @param name the EL name + * @return the resulting set of {@linkplain Bean beans} + * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} + * event is fired. + */ + Set> getBeans(String name); + + /** + * Apply the ambiguous dependency resolution rules to a set of {@linkplain Bean beans}. + *

+ * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, + * this method will only return beans discovered by the container before the {@link AfterBeanDiscovery} event is fired. + * + * @param a common type of the beans + * @param beans a set of {@linkplain Bean beans} of the given type + * @return the resolved bean, or null if null or an empty set is passed + * @throws AmbiguousResolutionException if the ambiguous dependency resolution rules fail + * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} + * event is fired. + */ + Bean resolve(Set> beans); + + /** + * Return an ordered set of {@linkplain ObserverMethod observer methods} for an event. + *

+ * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, + * this method will only return observers discovered by the container before the {@link AfterBeanDiscovery} event is fired. + * + * @param the type of the event + * @param event the event object + * @param qualifiers the event qualifiers + * @return the resulting set of {@linkplain ObserverMethod observer methods} + * @throws IllegalArgumentException if the runtime type of the event object contains a type variable + * @throws IllegalArgumentException if two instances of the same non repeating qualifier type are given + * @throws IllegalArgumentException if an instance of an annotation that is not a qualifier type is given + * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} + * event is fired. + */ + Set> resolveObserverMethods(T event, Annotation... qualifiers); + + /** + * Return an ordered list of enabled {@linkplain Interceptor 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 + * BeanManager/BeanContainer was injected or, in the Jakarta EE environment, + * the Jakarta EE component from whose JNDI environment namespace the + * BeanManager/BeanContainer was obtained. + *

+ * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, + * this method will only return interceptors discovered by the container before the {@link AfterBeanDiscovery} event is + * fired. + * + * @param type the type of the interception + * @param interceptorBindings the interceptor bindings + * @return the resulting set of {@linkplain Interceptor interceptors} + * @throws IllegalArgumentException if no interceptor binding type is given + * @throws IllegalArgumentException if two instances of the same interceptor binding type are given + * @throws IllegalArgumentException if an instance of an annotation that is not an interceptor binding type is given + * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} + * event is fired. + */ + List> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings); + + /** + * Test the given annotation type to determine if it is a {@linkplain jakarta.enterprise.context scope type}. + * + * @param annotationType the annotation type + * @return true if the annotation type is a {@linkplain jakarta.enterprise.context scope type} + */ + boolean isScope(Class annotationType); + + /** + * Test the given annotation type to determine if it is a {@linkplain jakarta.enterprise.context normal scope type}. + * + * @param annotationType the annotation type + * @return true if the annotation type is a {@linkplain jakarta.enterprise.context normal scope type} + */ + boolean isNormalScope(Class annotationType); + + /** + * Test the given annotation type to determine if it is a {@linkplain jakarta.inject.Qualifier qualifier type}. + * + * @param annotationType the annotation type + * @return true if the annotation type is a {@linkplain jakarta.inject.Qualifier qualifier type} + */ + boolean isQualifier(Class annotationType); + + /** + * Test the given annotation type to determine if it is a {@linkplain Stereotype stereotype}. + * + * @param annotationType the annotation type + * @return true if the annotation type is a {@linkplain Stereotype stereotype} + */ + boolean isStereotype(Class annotationType); + + /** + * Test the given annotation type to determine if it is an {@linkplain jakarta.interceptor.InterceptorBinding interceptor + * binding type} . + * + * @param annotationType the annotation to test + * @return true if the annotation type is a {@linkplain jakarta.interceptor.InterceptorBinding interceptor binding + * type} + */ + boolean isInterceptorBinding(Class annotationType); + + /** + * Obtains an active {@linkplain Context context object} for the given + * {@linkplain jakarta.enterprise.context scope} . + * + * @param scopeType the {@linkplain jakarta.enterprise.context scope} + * @return the {@linkplain Context context object} + * @throws ContextNotActiveException if there is no active context object for the given scope + * @throws IllegalArgumentException if there is more than one active context object for the given scope + */ + Context getContext(Class scopeType); + + /** + * Returns an instance of Event with specified type java.lang.Object and specified qualifier @Default + * It allows typesafe synchronous or asynchronous event firing without injection of {@link Event} built-in bean requirement. + * + * @return a new {@link Event} object whose event type is Object and qualifier @Default + * @since 2.0 + */ + Event getEvent(); + + + /** + * Obtains an {@link Instance} object to access to beans instances. + *

+ * 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 BeanManager/BeanContainer was injected + * or, in the Jakarta EE environment, the Jakarta EE component from whose JNDI environment namespace the + * BeanContainer was obtained, according to the rules of typesafe resolution. + *

+ * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, + * the Instance returned by this method will only give access to instances of beans discovered by the container + * before the {@link AfterBeanDiscovery} event is fired. + *

+ * Instances of dependent scoped beans obtained with this Instance must be explicitly destroyed by calling {@link Instance#destroy(Object)} + *

+ * If no qualifier is passed to {@link Instance#select} method, the @Default qualifier is assumed. + * + * @return an {@link Instance} object to request beans instances + * @throws IllegalStateException if called during application initialization, before the {@link AfterDeploymentValidation} + * event is fired. + * @since 2.0 + */ + Instance createInstance(); +} diff --git a/api/src/main/java/jakarta/enterprise/inject/spi/BeanManager.java b/api/src/main/java/jakarta/enterprise/inject/spi/BeanManager.java index 071e6694..0e278e12 100644 --- a/api/src/main/java/jakarta/enterprise/inject/spi/BeanManager.java +++ b/api/src/main/java/jakarta/enterprise/inject/spi/BeanManager.java @@ -19,18 +19,9 @@ import jakarta.el.ELResolver; import jakarta.el.ExpressionFactory; -import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.context.Dependent; -import jakarta.enterprise.context.spi.Context; -import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.context.spi.CreationalContext; -import jakarta.enterprise.event.Event; -import jakarta.enterprise.event.ObserverException; -import jakarta.enterprise.inject.AmbiguousResolutionException; import jakarta.enterprise.inject.InjectionException; -import jakarta.enterprise.inject.Default; -import jakarta.enterprise.inject.Instance; -import jakarta.enterprise.inject.UnsatisfiedResolutionException; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Annotation; import java.lang.reflect.Type; @@ -44,6 +35,10 @@ * Allows a portable extension to interact directly with the container. Provides operations for obtaining contextual references * for beans, along with many other operations of use to portable extensions. *

+ * + *

+ * In CDI Lite environment, attempting to obtain a {@link BeanManager} or invoking methods on it results in non-portable behavior. + *

* *

* Any bean may obtain an instance of BeanManager by injecting it: @@ -93,86 +88,7 @@ * @author David Allen * @author Antoine Sabot-Durand */ -public interface BeanManager { - - - /** - *

- * Obtains a contextual reference for a certain {@linkplain Bean bean} and a certain bean type of the bean. - *

- * - * @param bean the {@link Bean} object representing the bean - * @param beanType a bean type that must be implemented by any client proxy that is returned - * @param ctx a {@link CreationalContext} that may be used to destroy any object with scope - * {@link Dependent} that is created - * @return a contextual reference representing the bean - * @throws IllegalArgumentException if the given type is not a bean type of the given bean - * @throws IllegalStateException if called during application initialization, before the {@link AfterDeploymentValidation} - * event is fired. - */ - public Object getReference(Bean bean, Type beanType, CreationalContext ctx); - - /** - *

- * Obtains an injectable reference for a certain {@linkplain InjectionPoint injection point}. - *

- * - * @param ij the target injection point - * @param ctx a {@link CreationalContext} that may be used to destroy any object with scope - * {@link Dependent} that is created - * @return the injectable reference - * @throws UnsatisfiedResolutionException if typesafe resolution results in an unsatisfied dependency - * @throws AmbiguousResolutionException typesafe resolution results in an unresolvable ambiguous dependency - * @throws IllegalStateException if called during application initialization, before the {@link AfterDeploymentValidation} - * event is fired. - */ - public Object getInjectableReference(InjectionPoint ij, CreationalContext ctx); - - /** - * Obtain an instance of a {@link CreationalContext} for the given - * {@linkplain Contextual contextual type}, or for a non-contextual object. - * - * @param type of the instance - * @param contextual the {@link Contextual}, or a null value in the case of a non-contextual - * object - * @return the new {@link CreationalContext} - */ - public CreationalContext createCreationalContext(Contextual contextual); - - /** - * Return 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 BeanManager was injected or the Java EE component from whose JNDI - * environment namespace the BeanManager was obtained, according to the rules of typesafe resolution. If no - * qualifiers are given, the {@linkplain Default default qualifier} is assumed. - * - * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, - * this method will only return beans discovered by the container before the {@link AfterBeanDiscovery} event is fired. - * - * @param beanType the required bean type - * @param qualifiers the required qualifiers - * @return the resulting set of {@linkplain Bean beans} - * @throws IllegalArgumentException if the given type represents a type variable - * @throws IllegalArgumentException if two instances of the same non repeating qualifier type are given - * @throws IllegalArgumentException if an instance of an annotation that is not a qualifier type is given - * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} - * event is fired. - */ - public Set> getBeans(Type beanType, Annotation... qualifiers); - - /** - * Return the set of beans which have the given EL name and are available for injection in the module or library containing - * the class into which the BeanManager was injected or the Java EE component from whose JNDI environment namespace - * the BeanManager was obtained, according to the rules of EL name resolution. - * - * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, - * this method will only return beans discovered by the container before the {@link AfterBeanDiscovery} event is fired. - * - * @param name the EL name - * @return the resulting set of {@linkplain Bean beans} - * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} - * event is fired. - */ - public Set> getBeans(String name); +public interface BeanManager extends BeanContainer { /** * Returns the {@link PassivationCapable} bean with the given identifier. @@ -188,21 +104,6 @@ public interface BeanManager { */ public Bean getPassivationCapableBean(String id); - /** - * Apply the ambiguous dependency resolution rules to a set of {@linkplain Bean beans}. - * - * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, - * this method will only return beans discovered by the container before the {@link AfterBeanDiscovery} event is fired. - * - * @param a common type of the beans - * @param beans a set of {@linkplain Bean beans} of the given type - * @return the resolved bean, or null if null or an empty set is passed - * @throws AmbiguousResolutionException if the ambiguous dependency resolution rules fail - * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} - * event is fired. - */ - public Bean resolve(Set> beans); - /** * Validate a certain {@linkplain InjectionPoint injection point}. * @@ -255,42 +156,6 @@ public interface BeanManager { */ public List> resolveDecorators(Set types, Annotation... qualifiers); - /** - * Return an ordered list of enabled {@linkplain Interceptor 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 BeanManager was - * injected or the Java EE component from whose JNDI environment namespace the BeanManager was obtained. - * - * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, - * this method will only return interceptors discovered by the container before the {@link AfterBeanDiscovery} event is - * fired. - * - * @param type the type of the interception - * @param interceptorBindings the interceptor bindings - * @return the resulting set of {@linkplain Interceptor interceptors} - * @throws IllegalArgumentException if no interceptor binding type is given - * @throws IllegalArgumentException if two instances of the same interceptor binding type are given - * @throws IllegalArgumentException if an instance of an annotation that is not an interceptor binding type is given - * @throws IllegalStateException if called during application initialization, before the {@link AfterBeanDiscovery} - * event is fired. - */ - public List> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings); - - /** - * Test the given annotation type to determine if it is a {@linkplain jakarta.enterprise.context scope type}. - * - * @param annotationType the annotation type - * @return true if the annotation type is a {@linkplain jakarta.enterprise.context scope type} - */ - public boolean isScope(Class annotationType); - - /** - * Test the given annotation type to determine if it is a {@linkplain jakarta.enterprise.context normal scope type}. - * - * @param annotationType the annotation type - * @return true if the annotation type is a {@linkplain jakarta.enterprise.context normal scope type} - */ - public boolean isNormalScope(Class annotationType); - /** * Test the given annotation type to determine if it is a passivating {@linkplain jakarta.enterprise.context scope type}. * @@ -299,32 +164,6 @@ public interface BeanManager { */ public boolean isPassivatingScope(Class annotationType); - /** - * Test the given annotation type to determine if it is a {@linkplain jakarta.inject.Qualifier qualifier type}. - * - * @param annotationType the annotation type - * @return true if the annotation type is a {@linkplain jakarta.inject.Qualifier qualifier type} - */ - public boolean isQualifier(Class annotationType); - - /** - * Test the given annotation type to determine if it is an {@linkplain jakarta.interceptor.InterceptorBinding interceptor - * binding type} . - * - * @param annotationType the annotation to test - * @return true if the annotation type is a {@linkplain jakarta.interceptor.InterceptorBinding interceptor binding - * type} - */ - public boolean isInterceptorBinding(Class annotationType); - - /** - * Test the given annotation type to determine if it is a {@linkplain Stereotype stereotype}. - * - * @param annotationType the annotation type - * @return true if the annotation type is a {@linkplain Stereotype stereotype} - */ - public boolean isStereotype(Class annotationType); - /** * Obtains the set of meta-annotations for a certain {@linkplain jakarta.interceptor.InterceptorBinding interceptor binding * type} . @@ -384,17 +223,6 @@ public interface BeanManager { */ public int getInterceptorBindingHashCode(Annotation interceptorBinding); - /** - * Obtains an active {@linkplain Context context object} for the given - * {@linkplain jakarta.enterprise.context scope} . - * - * @param scopeType the {@linkplain jakarta.enterprise.context scope} - * @return the {@linkplain Context context object} - * @throws ContextNotActiveException if there is no active context object for the given scope - * @throws IllegalArgumentException if there is more than one active context object for the given scope - */ - public Context getContext(Class scopeType); - /** * Returns a {@link jakarta.el.ELResolver} that resolves beans by EL name. * @@ -590,39 +418,4 @@ public Bean createBean(BeanAttributes attributes, Class beanClass, */ InterceptionFactory createInterceptionFactory(CreationalContext ctx, Class clazz); - - /** - * - * Returns an instance of Event with specified type java.lang.Object and specified qualifier @Default - * It allows typesafe synchronous or asynchronous event firing without injection of {@link Event} built-in bean requirement. - * - * @return a new {@link Event} object whose event type is Object and qualifier @Default - * @since 2.0 - */ - Event getEvent(); - - - /** - * - * Obtains an {@link Instance} object to access to beans instances. - * - * 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 BeanManager was injected or the Java EE component from whose JNDI - * environment namespace the BeanManager was obtained, according to the rules of typesafe resolution. - * - * Note that when called during invocation of an {@link AfterBeanDiscovery} event observer, - * the Instance returned by this method will only give access to instances of beans discovered by the container - * before the {@link AfterBeanDiscovery} event is fired. - * - * Instances of dependent scoped beans obtained with this Instance must be explicitly destroyed by calling {@link Instance#destroy(Object)} - * - * If no qualifier is passed to {@link Instance#select} method, the @Default qualifier is assumed. - * - * @return an {@link Instance} object to request beans instances - * @throws IllegalStateException if called during application initialization, before the {@link AfterDeploymentValidation} - * event is fired. - * @since 2.0 - */ - Instance createInstance(); - } diff --git a/api/src/main/java/jakarta/enterprise/inject/spi/CDI.java b/api/src/main/java/jakarta/enterprise/inject/spi/CDI.java index 344ec8b3..b50f192d 100644 --- a/api/src/main/java/jakarta/enterprise/inject/spi/CDI.java +++ b/api/src/main/java/jakarta/enterprise/inject/spi/CDI.java @@ -152,8 +152,19 @@ private static void findAllProviders() { /** * Get the CDI BeanManager for the current context * - * @return the BeanManager + * @return the {@link BeanManager} */ public abstract BeanManager getBeanManager(); + /** + * Get the CDI {@link BeanContainer} for the current context. + * + * Default implementation just forwards the call to {@link #getBeanManager()}. + * + * @return the {@link BeanContainer} + */ + public BeanContainer getBeanContainer() { + return getBeanManager(); + } + }