Google and Spring are proposing a JSR to standardize a set of dependency injection related annotations. I've been asked by several people to comment on this and how it relates to JSR-299.
First, the proposed JSR would define a strict subset of the functionality that already exists in 299, so there would be no difficulty in having 299 containers support the proposed annotations. And, of course, any implementation of 299 has functionality that goes well beyond what is being proposed here. So this new JSR proposal is not in competition with 299.
Second, the annotations proposed in this JSR proposal are more or less equivalent to a subset of the annotations defined in 299, modulo naming:
- @Qualifier is equivalent to @BindingType,
- @Scope is equivalent to @ScopeType,
- @Singleton is equivalent to @ApplicationScoped,
- @Named is just a built-in binding type, and
- the Provider<X> interface is equivalent to Instance<X>.
- @Inject is more or less similar to @Initializer.
Now, I think it would be a huge mistake to introduce a second set of annotations which are semantically identical to those in 299 and address the exactly the same problem. So I interpret this JSR proposal as saying: let's take a subset of the annotations that are already defined in 299, split them out into a different package, and make them consumable to other containers that do dependency injection. This is certainly doable, and quite appealing on some level, but I'm still waiting to be convinced that it's really worth doing.
The problem is that the new JSR proposal has been carefully scoped so that it includes only the things that the folks proposing the JSR (i.e. Spring and Guice) already agree on, and leaves out all possible areas of divergence between existing dependency injection solutions. It's as if the folks proposing the JSR recognize that they're simply unable to reach agreement on all the hard stuff, and want to keep doing that stuff in their own incompatible, proprietary ways.
For example, the proposal leaves out of scope the following interesting issues:
- how do I interact with the dependency injection container?
- what kinds of objects are injectable?
- how do I indicate to the container that something is injectable, and declare its qualifiers?
- what is the lifecycle of the injected objects?
- how do I define different deployment scenarios, with different implementations of injected types?
- what restrictions exist when I have circular dependencies, serialized scopes, etc?
- what SPIs exist to allow third-party frameworks to integrate with the container?
- what are the standard set of scopes that exist in a web environment?
(This is by no means an exhaustive list.)
But from the point of view of the application developer, without a specification that addresses all these questions, there's just no possibility to build portable applications using these annotations. And portability is the usual goal of a JSR, right?
By contrast, JSR-299 does nail down all this stuff, and more: it's a complete specification for containers that do dependency injection, and for portable applications that run on those containers. To my mind, that's much more useful.
(UPDATED to correct interpretation of Provider interface.)