[Spring] 의존성 주입(DI)과 제어의 역전(IoC) 이해하기
KUKJIN LEE • 3주 전 작성
Spring Core는 의존성 주입(Dependency Injection, DI)과 제어의 역전(Inversion of Control, IoC) 두 가지는 Spring Framework의 기본 요소입니다.
1. 의존성 주입(Dependency Injection, DI)
의존성 주입은 클래스 간의 의존성을 외부에서 주입해 객체 생성의 책임을 Spring 컨테이너가 담당합니다. 코드의 결합도가 낮아지고, 테스트 및 확장이 쉬워집니다.
-
실무 예시: 설정 파일(XML) 또는 어노테이션을 통해 객체 간의 의존성을 관리할 수 있습니다.
@Service
public class OrderService {
private final PaymentService paymentService;
// 생성자 주입 (Constructor Injection)
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void processOrder() {
paymentService.processPayment();
}
}
@Service
public class PaymentService {
public void processPayment() {
// 결제 처리 로직
}
}
Spring은 OrderService
객체를 생성할 때 PaymentService
객체를 자동으로 주입해주므로, 두 클래스는 결합되지 않습니다. 이는 확장성 및 테스트의 용이성을 보장합니다.
(이해를 돕기 위해 설명하자면, `OrderService`와 `PaymentService`의 분리를 뜻합니다. 주문 관련은 `OrderService`에 지불 관련은 `PaymentService`에 의존성을 주입한다는 뜻이죠.)
2. 제어의 역전(Inversion of Control, IoC)
제어의 역전은 객체의 생성과 생명 주기 관리를 개발자가 아닌 Spring 컨테이너에 맡기는 패턴입니다. 이를 통해 코드의 유연성이 높아지며, Spring 컨테이너는 애플리케이션이 시작될 때 필요한 객체들을 자동으로 생성하고 관리합니다.
-
실무 예시:
@Component
,@Service
,@Repository
등의 어노테이션을 통해 Spring이 관리하는 Bean을 정의할 수 있습니다.
@Component
public class ProductRepository {
public List<String> findAllProducts() {
// 제품 목록 조회 로직
return List.of("Laptop", "Smartphone", "Tablet");
}
}
@Service
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public List<String> getProducts() {
return productRepository.findAllProducts();
}
}
Spring은 ProductService
클래스에서 ProductRepository
를 자동으로 주입하고, 이를 관리합니다. 이렇게 함으로써 애플리케이션의 객체 간 의존성을 효율적으로 관리할 수 있습니다.
(쉽게 말해, 개발자는 비즈니스 로직에만 집중하고, 객체 생성과 생명 주기 관리는 Spring 컨테이너가 합니다. 객체 생성과 생명 주기 관리에 대한 권한을 뺏겨서 제어의 역전이라고 부른다! 생각하시면 편합니다.)