The problem
Among the shortcomings of CDI (1.0) as a general purpose DI container is the lack of what Spring 3.+ users know as profiles (not to mention Guice, which is much more expressive due to its Java EDSL approach). The CDI feature which looks closest at a first glance is the concept of
alternatives, quickly turns out to be utterly useless: You can annotate your beans directly (or indirectly, via stereotypes) as
@Alternatives and then choose among them for one bean-archive (read "jar") only b
y selecting them in the META-INF/beans.xml file. So, there is no way to switch between wiring-profiles without repackaging (possibly all) the jars in the deployment-unit.
CDI 1.1 improves very slightly on this by allowing a "global" selection in only one of the "beans.xml" which is still far below par.
The implementation-selector pattern
My currently favored work-around consists of the following steps
- define an enumeration of profiles
- define a qualifier annotation referring to one of those profiles
- annotate service alternatives with the above profile-qualifier
- define a producer selecting the appropriate profile programmatically, publishing it to "@Default" injection points.
In some more detail:
Profile enum and annotation
Let's start with the annotation:
The Enum's slightly more interesting, because it sports a reference to an annotation literal which comes in handy later, when we select the right instance:
Annotate your service alternatives
Now we can annotate our service alternatives like
@InProfile(IN_MEMORY_DB) public class SampleSvcForInMemoryDb implements SampleSvc { ...
Define the implementation-selector
This is just a bean containing a producer method like this:
Thanks to the @Any annotation, it gets all available instances injected. It then selects the appropriate one for the
activeProfile, which is a member variable in this sample, but can, of course be any method-call. Unfortunately, CDI does not allow a useful generification of that pattern, as far as I could see. It's still inferior to what other frameworks offer, but if CDI is a set standard, it's usable.