◆ TURNING · SPRING

DI — 의존성 주입

Java와 Spring의 철학 — 읽기 자료

📍 지금 어디를 만지고 있나요?
브라우저
Tomcat
Spring 컨테이너 + @Autowired
Controller
DB

이 차시의 핵심 용어

DI (Dependency Injection)의존성 주입. 필요한 객체를 외부(컨테이너)에서 끼워넣어주는 방식. IoC 의 실제 구현.
@Component 계열클래스를 Bean 으로 등록하는 어노테이션. @Service, @Repository, @Controller 모두 같은 역할 + 의미상의 구분.
@Autowired컨테이너 안의 적절한 Bean 을 자동으로 찾아 주입하는 어노테이션.
생성자 주입생성자 매개변수로 의존성을 받는 방식. 가장 권장되는 방식.

1. IoC 와 DI 의 관계

전 차시 IoC 는 발상(원칙)이고, 이번 차시 DI 는 그 발상을 코드로 실제 구현하는 방식입니다.

IoC = "객체 제어권을 외부에 위임한다" ← 큰 발상 DI = "외부에서 의존성을 주입한다" ← IoC 의 구현 방법

2. 비유 — 재료 배달

요리사가 직접 장보지 않는다

요리사(클래스)가 매번 시장 가서 재료(부품)를 사 오면 요리에 집중할 수 없습니다. 「필요한 재료를 주방으로 배달받는」 방식이 DI. 요리사는 요리(비즈니스 로직)에만 집중하면 됩니다.

3. Spring 코드

@Service
public class OrderService {

    @Autowired
    private MessageSender sender;

    public void order() {
        sender.send("주문 완료");
    }
}

핵심 어노테이션 두 개

4. 등록 어노테이션의 종류

어노테이션 의미적 자리
@Component일반 Bean (특별한 의미 없음)
@Service비즈니스 로직 계층
@Repository데이터 접근 계층 (DB 다루는 곳)
@Controller웹 요청 진입점

기능적으로는 모두 동일합니다 — Spring 이 같은 일을 합니다. 의미적으로 어떤 계층에 속한 클래스인지를 표시할 뿐.

5. 주입의 3 가지 방식

① 필드 주입 (간단)

@Service
class OrderService {
    @Autowired
    private MessageSender sender;  // 필드에 직접
}

② 생성자 주입 (권장)

@Service
class OrderService {
    private final MessageSender sender;

    @Autowired  // (생성자가 1개면 생략 가능)
    public OrderService(MessageSender sender) {
        this.sender = sender;
    }
}

③ setter 주입

@Service
class OrderService {
    private MessageSender sender;

    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }
}
실무에선 생성자 주입

생성자 주입이 ① 의존성을 final 로 만들 수 있고 ② 테스트가 쉽고 ③ 순환 참조를 컴파일 타임에 잡아주기 때문에 가장 권장됩니다. 학습 단계에선 필드 주입으로 시작해도 OK.

6. v1 → v2 비교

전 차시 (수동 IoC)
// main 에서 직접
MessageSender s = new GmailSender();
OrderService svc = new OrderService(s);
svc.order();
이번 차시 (Spring DI)
@Service
class OrderService {
    @Autowired
    private MessageSender sender;
}
// main 에서 직접 주입할 필요 없음

7. Before / After

전 차시 끝

IoC 의 발상은 알지만 직접 main 에서 주입했다.

이번 차시 끝

@Autowired 한 줄이면 자동 주입. Spring 의 가장 핵심적인 어노테이션 두 개 (@Service, @Autowired) 를 안다.