Understanding Dependency Injection and Spring IoC: From Direct Instantiation to Factory and Reflection
This article explains why dependency injection reduces coupling compared to direct object creation, demonstrates traditional instantiation, interface programming, factory method, and reflection techniques, and shows how Spring IoC combines these concepts to manage object lifecycles in Java backend development.
Hello everyone, I am a senior architect.
Question: In learning the Spring framework, why does dependency injection lower code coupling compared to creating objects with new ?
1. Traditional object creation
Usually we create objects directly:
WuliCar wuli = new WuliCar();
wuli.run();When the business needs change (e.g., replace a Wuling car with a BMW or a helicopter), every place where the concrete class is instantiated must be modified, leading to massive code changes.
2. Interface programming
Define a common interface to decouple the client from concrete implementations:
public interface vehicle {
void work();
}Implement the interface for different vehicles:
public class Baoma implements vehicle {
@Override
public void work() {
System.out.println("BMW runs");
}
}
public class ZhiShenJi implements vehicle {
@Override
public void work() {
System.out.println("Helicopter flies");
}
}Now the client only depends on the vehicle interface; switching implementations only requires changing the instantiation point.
3. Factory method
Encapsulate object creation in a factory class:
class VehicleFactory {
VehicleFactory() {}
public static Vehicle getInstance(String type) {
Vehicle result = null;
if ("car".equals(type)) {
result = new Car();
}
if ("zhishenji".equals(type)) {
result = new ZhiShenJi();
}
return result;
}
}Clients request a vehicle by name, e.g., Vehicle vehicle = VehicleFactory.getInstance("zixingche"); vehicle.work(); , so only the factory needs to know the concrete class.
4. Reflection
Further improve flexibility by reading the desired type from a configuration file and creating the instance via reflection:
Vehicle vehicle = VehicleFactory.getInstance(readFromConfigFile);
vehicle.work();
// Desired: zixingche
// After change: zixingche.work();This way, changing the implementation requires editing only the configuration file, not the source code.
5. Spring IoC
Spring's Inversion of Control container implements the factory‑plus‑reflection approach automatically, managing object lifecycles and wiring dependencies, thus achieving low coupling without manual factory code.
6. Summary
Dependency injection means the required objects are provided by a container rather than created manually, promoting orthogonal (loosely‑coupled) design.
The caller declares a component and receives it; the container handles lookup, creation, and lifecycle management.
Developers can focus on business logic while the framework manages object creation and destruction.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.