Reputation: 2787
I find it odd that that I can't find this information, so please direct me to a creditable source if possible. This questions pertains only to Java.
In short, I want to know how dependency injections actually happens syntactically.
My understanding of dependency injection is the following:
public class Car {
private Engine engine
@Inject
public Car(Engine engine) {
this.engine = engine
}
}
Is the equivalent of
public class Car {
private Engine engine
public Car(Engine engine) {
this.engine = engine
}
}
Where the keyword @Inject
is syntactic sugar to let Java know that the dependency engine
is to be injected. This way Car
won't be responsible for creating engine
and therefore have a hard dependency of Engine
. However, no examples have shown me how to inject it. In short:
public MyClass {
public static void main(String[] args) {
ToyotaEngine toyotaEngine = new ToyotaEngine();
HondaEngine hondaEngine = new HondaEngine();
// ??? which one to inject?
Car myCar = new Car(); // syntax?
}
}
How do I actually trigger the injection? Simply call new Car()
and Engine
will be pass to the constructor for me? How does Java know which Engine
to inject?
Everything I've googled pertains to how to use the @Inject
annotation on the class but nothing about how to actually trigger it. This article describes a configuration that looks specific to Spring and doesn't explain much. And I'm not sure what Spring is.
Upvotes: 6
Views: 11266
Reputation: 1007
Maybe this article (https://www.objc.io/issues/11-android/dependency-injection-in-java/) can explain, how the concept DI works in general.
In order to use DI, you need to pick a DI framework. Each framework then provides a mechanism to do and trigger DI. Spring is a framework that uses DI, but it's also more than DI and designed to deal with Server-Client-based WebApps and Rest-Services, which makes it hard to single out the sole DI aspects.
Upvotes: 1
Reputation: 77167
There is no "syntax" about it, and @Inject
is not syntactic sugar. An annotation is a piece of metadata that gets recorded on an element (class, method, field, etc.), and then other software has a chance to inspect it. In the case of @Inject
, some framework that you're using (Spring, CDI, Guice) looks for the annotation and, if present, executes some code that looks up and provides you with the dependency. (This is typically called a container because it contains a bunch of objects that can be looked up and injected for you. Among other things, Spring provides a DI container.)
The constructor (or setter) works entirely normally, and you can't just use new Car()
. Instead, the framework, which has found an Engine
somewhere, invokes new Car(engine)
for you, passing in that object. If you're simply using new
, then you have to provide your own values; this is very useful for tests, where you can pass in mocks or test data.
(This, by the way, is the reason that using constructor injection is nearly always the best choice; it prevents you from using new Car()
when there are hidden dependencies, which wouldn't be initialized properly.)
Upvotes: 7