IoC is a design principle where the control of object creation and management is transferred from the application code to an external container (Spring Container).
DI is the implementation of IoC where dependencies are injected into objects rather than objects creating their dependencies.
// Without DI - tight coupling
public class UserService {
private UserRepository userRepository = new UserRepository(); // Tight coupling
}
// With DI - loose coupling
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository; // Dependency injected
}
}