I could not find a clear and simple explanation. How are they different? Could you please explain? Which was first and which is better and for what?
The concepts of Dependency Injection (DI) and Inversion of Control (IoC) existed long before Spring was introduced. However, I believe Spring played a significant role in popularizing these concepts within the Java community. Originally, Spring used XML-based configuration for defining beans, which seems quite cumbersome by today's standards. When Java 5 was released, Spring started incorporating Java annotations to streamline its configuration process, aligning it with XML-based configurations.
Around the same time, Google introduced Guice 1.0, claiming it was 100 times faster than Spring. Guice was designed specifically for Java 5, leveraging its new language features.
Meanwhile, JBoss (acquired by Red Hat at the time) incubated JBoss Seam, which aimed to unify the programming model in J2EE/Java EE. Many of the core concepts from JBoss Seam eventually evolved into CDI.
Contexts and Dependency Injection (CDI) was introduced as a standard specification in Java EE 6. Before its release, SpringSource (the company behind the Spring Framework at the time) and Google collaborated on developing a lightweight Dependency Injection specification for Java SE. Their goal was to extract the core DI concepts from CDI and define a minimal API. This specification included only a few fundamental annotations and types, such as, @Inject
, @Qualifier
, @Named
, @Scope
, @Singleton
, Provider
, etc. Today, this specification is known as Jakarta Dependenccy Injection in the Jakarta EE ecosystem.
Following the release of Java EE 6, both the Spring Framework and Google Guice implemented this specification in the newer versions. So you can use Jakarta standard @Inject
annotation in the latest Spring and Guice to replace the framework specific facitlites when including jakarta.inject
(Spring 6 and Guice 7) or old javax.inject
(the earlier versions of both) in classpath. This specification is not exclusive to these two frameworks—it is also used in other projects like Micronaut, the core of Eclipse 4 platform and JUnit 5.
However, the Jakarta Dependency Injection specification itself has remained largely unchanged over the years, apart from a namespace change when migrating to the Eclipse Foundation.
Jakarta CDI is built upon the Jakarta Dependency Injection specification. Weld, the reference implementation of CDI, also provides its own implementation of Jakarta Dependency Injection. Today, most Jakarta EE providers, including GlassFish, WildFly and Payara use Weld as their CDI implementation. Others, such as Apache TomEE, rely on Apache OpenWebBeans instead.
In Jakarta EE discussions, CDI is almost always the focus, while Jakarta Dependency Injection is rarely mentioned directly. The most commonly used annotations from Jakarta Inject are @Inject
and @Qualifier
. Occasionally, developers use @Named
and @Singleton
, but @Scope
and Provider
are rarely needed because CDI provides more advanced features for managing bean scopes and producing beans.
Here is a brief review of the history of DI and the origins of standards and open source projects. Technology itself is not good or bad. Choosing a technology stack that suits your team is the first priority.