What is the difference between using:
WeldContainer se = new Weld().initialize();
or
SeContainer se = SeContainerInitializer.newInstance().initialize();
I just want to use @Injection
and @Produce
annotations, but I have not found the difference between these two ways of initializing an object instance.
Context and Dependency Injection (CDI) is a specification. That means it defines an API only and does not provide an implementation. That's why you have to include an implementation such as Weld in order to actually use the API. The WeldContainer
class is vendor-specific whereas the SeContainer
interface is part of the specification. The former implements the latter.
The SeContainerInitializer
class, which is part of the API, will delegate to the implementation included with the application. So if you use Weld as the implementation then ultimately using SeContainerInitializer
and SeContainer
is the same as using Weld
and WeldContainer
"under the hood".
From a purist's perspective it's best to rely only on the specification's interface and never directly depend on the implementation. That way you can swap vendors if and when you need to since you're using functionality common to all implementations. However, often times an implementation provides more functionality than what's required by the specification. In order to use that functionality you have to directly depend on the implementation.
In other words, whether you use Weld
/ WeldContainer
or SeContainerInitialializer
/ SeContainer
depends on the (current and future) requirements of your application. When in doubt, program to the interface.
Note this separation between the API and implementation is not unique to CDI. Pretty much the entire Java EE—or as it's now known, Jakarta EE—API works this way. An example would be the Java Persistence API (JPA) and Hibernate or EclipseLink (two implementations). For an example within Java SE there's the Java Database Connectivity (JDBC) API and the various implementations (i.e. drivers).