About software development for the enterprise. Focus on Java EE and more general Java platforms.
You'll read a lot about Conferences, Java User Groups, Java EE, Integration, AS7, WildFly, EAP and other technologies that hit my road.

Tuesday, January 19, 2010

JSR-299 CDI portable extensions

08:59 Tuesday, January 19, 2010 Posted by Markus Eisele
,
One of my fav features of the new CDI spec is the ability to integrate custom extensions. The portable extensions spi is the place to start over with it.
You can find some examples of portable extensions in gavins blog. The latest weld reference documentation (weld-reference.pdf, 867 KiB, application/pdf) contains a chapter (16) with more details about the extension spi.
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.

Getting started is straight forward. (I was using NetBeans 6.8 with this example)
Add a webproject and a separate java library project. Push whatever is needed to your webproject and don't forget to put an empty beans.xml in your WEB-INF/ folder.
Now, start writing your extension.

1) Create a java class
that implements the marker interface javax.enterprise.inject.spi.Extension


public class MyExtension implements Extension {
//...
}

2) Register your extension
as a provider by creating a folder named META-INF/services/ in your java library project and putt a file named javax.enterprise.inject.spi.Extension in it. This file has to contain the full qualified name of your extension class (in my case net.eisele.cdi.extensions.MyExtension))

3) Implement the extension logic.
Basically extensions listen to events fired by the CDI container and are able to modify the containers metamodel. The events fired are one or all of the following:
javax.enterprise.inject.spi.BeforeBeanDiscovery
javax.enterprise.inject.spi.ProcessAnnotatedType
javax.enterprise.inject.spi.ProcessInjectionTarget and ProcessProducer
javax.enterprise.inject.spi.ProcessBean and ProcessObserverMethod
javax.enterprise.inject.spi.AfterBeanDiscovery
javax.enterprise.inject.spi.AfterDeploymentValidation

You have to add your business methods and declare an @Observes for every event you are willing to catch. Example:

void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
log.info("Begin the scanning process");
}


4) You can have a BeanManager
injected to your methods, too.

public void getBeanManager(@Observes BeanManager bm)

The nerve center for extending CDI is the BeanManager object. The BeanManager interface let you obtain beans, interceptors, decorators, observers and contexts programmatically.

5) You can inject your new extension
even it is not really a bean.

@Inject
MyExtension ext;

or

@Inject
MyBean(MyExtension myExtension) {
myExtension.doSomething();
}


If you deploy your app to GlassFish v3 you see something like this in your logfile:
INFO: Begin the scanning process

That was it. You got your first CDI extension up and running.