SeamFramework.orgCommunity Documentation
CDI is intended to be a foundation for frameworks, extensions and integration with other technologies. Therefore, CDI exposes a set of SPIs for the use of developers of portable extensions to CDI. For example, the following kinds of extensions were envisaged by the designers of CDI:
integration with Business Process Management engines,
integration with third-party frameworks such as Spring, Seam, GWT or Wicket, and
new technology based upon the CDI programming model.
More formally, according to the spec:
A portable extension may integrate with the container by:
Providing its own beans, interceptors and decorators to the container
Injecting dependencies into its own objects using the dependency injection service
Providing a context implementation for a custom scope
Augmenting or overriding the annotation-based metadata with metadata from some other source
The nerve center for extending CDI is the BeanManager
object.
The BeanManager
interface lets us obtain beans, interceptors, decorators,
observers and contexts programmatically.
public interface Manager {
public Object getReference(Bean<?> bean, Type beanType, CreationalContext<?> ctx);
public Object getInjectableReference(InjectionPoint ij, CreationalContext<?> ctx);
public <T> CreationalContext<T> createCreationalContext(Contextual<T> contextual);
public Set<Bean<?>> getBeans(Type beanType, Annotation... bindings);
public Set<Bean<?>> getBeans(String name);
public <X> Bean<? extends X> getMostSpecializedBean(Bean<X> bean);
public Bean<?> getPassivationCapableBean(String id);
public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans);
public void validate(InjectionPoint injectionPoint);
public void fireEvent(Object event, Annotation... bindings);
public <T> Set<ObserverMethod<?, T>> resolveObserverMethods(T event, Annotation... bindings);
public List<Decorator<?>> resolveDecorators(Set<Type> types, Annotation... bindings);
public List<Interceptor<?>> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings);
public boolean isScope(Class<? extends Annotation> annotationType);
public boolean isNormalScope(Class<? extends Annotation> annotationType);
public boolean isPassivatingScope(Class<? extends Annotation> annotationType);
public boolean isQualifier(Class<? extends Annotation> annotationType);
public boolean isInterceptorBindingType(Class<? extends Annotation> annotationType);
public boolean isStereotype(Class<? extends Annotation> annotationType);
public Set<Annotation> getInterceptorBindingTypeDefinition(Class<? extends Annotation> bindingType);
public Set<Annotation> getStereotypeDefinition(Class<? extends Annotation> stereotype);
public Context getContext(Class<? extends Annotation> scopeType);
public ELResolver getELResolver();
public ExpressionFactory wrapExpressionFactory(ExpressionFactory expressionFactory);
public <T> AnnotatedType<T> createAnnotatedType(Class<T> type);
public <T> InjectionTarget<T> createInjectionTarget(AnnotatedType<T> type);
}
We can obtain an instance of BeanManager
via injection:
@Inject BeanManager beanManager
Java EE components may obtain an instance of BeanManager
from JNDI by looking up the name
java:comp/BeanManager
. Any operation of BeanManager
may be called at any
time during the execution of the application.
Let's study some of the interfaces exposed by the BeanManager
.
Instances of the interface Bean
represent beans. There is an instance of
Bean
registered with the BeanManager
object for every bean in the
application.
public interface Bean<T> extends Contextual<T> {
public Set<Type> getTypes();
public Set<Annotation> getQualifiers();
public Class<? extends Annotation> getScope();
public String getName();
public Set<Class<? extends Annotation>> getStereotypes();
public Class<?> getBeanClass();
public boolean isAlternative();
public boolean isNullable();
public Set<InjectionPoint> getInjectionPoints();
}
It's possible to implement the Bean
interface and register instances by calling
AfterBeanDiscovery.addBean()
(AfterBeanDiscovery
is a built-in event type
that an extension can observe) to provide support for new kinds of beans, beyond those defined by the CDI
specification. For example, we could use the Bean
interface to allow objects managed by
another framework to be injected into beans.
There are two subinterfaces of Bean
defined by the CDI specification:
Interceptor
and Decorator
.
The Context
interface supports addition of new scopes to CDI, or extension of the built-in
scopes to new environments.
public interface Context {
public Class<? extends Annotation> getScope();
public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext);
public <T> T get(Contextual<T> contextual);
boolean isActive();
}
For example, we might implement Context
to add a business process scope to CDI, or to add
support for the conversation scope to an application that uses Wicket.