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.