Dynamic beans in CDI 2.0
A Bean<T> is a kind of factory for beans, that makes types available for injection, lookup via the bean manager, or by referencing them in expression language. CDI producers (via the @Produces annotation) fulfil a somewhat similar role, but they essentially only make the "create instance" method dynamic; the rest (like scope, types, etc) is more or less static. A programmatically added Bean<T> essentially makes all those aspects dynamic.
As the previous article showed, dynamically adding such Bean<T> is a bit more work and it's quite verbose, as well as a little complex as the developer has to find out what to return as a default for various methods that are not directly of interest.
CDI 2.0 has addressed some of the above issues by providing a very convenient builder that not only makes creating a Bean<T> instance far less verbose, but also takes away most of the guesswork. The following shows an example:
public class CdiExtension implements Extension { public void afterBean(final @Observes AfterBeanDiscovery afterBeanDiscovery) { afterBeanDiscovery .addBean() .scope(ApplicationScoped.class) .types(MyBean.class) .id("Created by " + CdiExtension.class) .createWith(e -> new MyBeanImpl("Hi!")); } }
The above makes a bean available for injection into MyBean injection points and with the @ApplicationScoped scope, backed by a MyBeanImpl class.
A fully working example is provided in the Java EE 8 Samples project.
The example was tested on Payara Server 5, of which a snapshot can be downloaded from the snapshot repository. An initial alpha will be released very soon, but in the mean time the latest version can be downloaded here:
payara-5.0.0.173-SNAPSHOT.zip.
Arjan Tijms
This comment has been removed by the author.
ReplyDeletePlease write a book with "CDI 2.0 Essentials" soon. It will make it easier to comprehend the new version of CDI.
ReplyDeleteGood luck
RK