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.