CDI Qualifiers are Values

I had this realization today that I’m frankly not sure quite what to do with.

The realization, briefly put, is that CDI qualifiers are values for various unnamed aspects.  They are not those aspects themselves.

For example, the often-seen-in-CDI-examples qualifier @Synchronous is really a possible value for a hypothetical aspect called—I don’t know—synchronicity.  @Yellow is really a value for a hypothetical aspect called, presumably, color.  And yet we’re always left to infer what the aspect is from the qualifier itself (representing a possible value for that unnamed aspect).

We do this in English too: if you say “get me my yellow coat,” I don’t have to ask you about what aspect for which yellow serves as a value.  But that’s what’s going on.

This also led me to realize that, seen through a certain lens, there are other implicit qualifiers that are present everywhere, in an abstract sense (not actually in code).  For example, if I run my CDI application in a test environment, then there is this abstract sense in which all of my injection points (and their corresponding beans or producer methods) are semantically qualified with something like @Test, where @Test is a possible value for a hypothetical environment aspect.

What other aspects are there?  Well, there’s environment, I guess, and project stage, maybe, and data center ID, I guess, and region, and phase of the moon…and all of the other things that go into describing my application’s effective coordinates, all of which affect, potentially, what sorts of things are injected.

For non-configuration injection points, when you inject a Frobnicator, there’s only one choice (perhaps disambiguated from a set of alternatives via a META-INF/beans.xml file). So a lot of this just stays in thought experiment land: the Frobnicator you get is, well, the one you get. It’s not like there are dozens of them lying around.

But with configuration, you’re usually talking about plain types (String), indexed under names, suitable for certain worlds and not for others (“don’t use the production database url!”).

Standard procedure among the 34,472 CDI configuration “frameworks” out there is to make a “qualifier” called, say, @Config, with all @Nonbinding-annotated elements, thus rendering it not much of a qualifier at all (primarily so that a single producer method can use it), and then a producer method or a CDI extension or something that is actually in charge of figuring out what the name of the configuration item is whose value should be retrieved (thus turning the “qualifier” into a name, really). Note how using @Config here confuses the fact that a qualifier is a value, not an aspect.

(CDI itself (well, JSR-330 actually) gets confused in a similar way with its own annotations!  The javax.inject.Named “qualifier” is, note, not a value, but an aspect.  The value of the aspect is given by the annotation’s value() element.)

So what to do with all this?  I am not sure as of this writing, but I have this nagging sense that there’s the germ of a more powerful, more properly-aligned-with-the-spirit-of-CDI configuration extension brewing in here.

Author: Laird Nelson

Devoted husband and father; working on Helidon at the intersection of Java, Jakarta EE, architecture, Kubernetes and microservices at Oracle; open source guy; Hammond B3 player and Bainbridge Islander.

2 thoughts on “CDI Qualifiers are Values”

Comments are closed.

%d bloggers like this: