◇ PART · SPRING

IoC — 제어 역전

제어권은 누구에게 있는가

학습 목표

  • IoC 의 의미를 한 문장으로 말한다
  • 제어권이 개발자에서 컨테이너로 어떻게 넘어가는지 안다
  • IoC 가 강한 결합을 어떻게 푸는지 이해
  • 「Bean」 이라는 용어를 안다

⚠️ 전 차시의 답답함 — 강한 결합

문제의 원인

"내가 직접 new 로 객체를 만든다" → 만든 객체에 꽉 묶임

발상의 전환: "누군가 만들어주면 되지 않나?" 누가? 외부의 누군가가요.

🛠️ IoC (Inversion of Control)

「내가」 → 「외부에서」

객체의 생성·관리 권한을 개발자에서 외부 컨테이너로 넘기는 설계 원칙. 제어권이 뒤집혔다고 해서 「Inversion of Control = 역전」.

택시 뒷좌석에 앉은 손님처럼 — 운전대를 잡지 않아도 목적지에 도착합니다.

택시 뒷좌석

비유 — 택시 뒷좌석

기존 방식IoC 방식
내가 운전자
핸들을 잡고 직접 운전
길 막히면 내가 새 길 찾기

= 객체를 직접 new
나는 뒷좌석 손님
목적지만 말함
택시(컨테이너) 가 알아서 운전

= 컨테이너가 객체 관리

코드의 변화

BEFORE — 직접 new

public class OrderService {
    private MailSender mail
        = new GmailSender();
    // 내가 직접 만들고 관리
}
AFTER — IoC

public class OrderService {
    private MailSender mail;
    // 받기만 한다
    // 만드는 건 컨테이너가
}

👉 new 가 사라졌습니다. 「누가 객체를 만들어주는지」를 클래스 안에서는 모릅니다.

누가 만들어주는가 — Spring 컨테이너

Spring 컨테이너 가 합니다. 애플리케이션 시작 시:

  1. 컨테이너가 우리 코드를 스캔
  2. 등록할 클래스 (@Component, @Service 등) 발견
  3. 각 클래스의 인스턴스를 미리 만들어 보관
  4. 필요한 곳 (다른 클래스의 필드) 에 자동 주입

Bean — 컨테이너가 관리하는 객체

이 컨테이너가 관리하는 객체를 Bean 이라 부릅니다.

  • 애플리케이션 시작 시 한 번 만들어짐 (싱글톤 기본)
  • 이후 어디서든 같은 객체를 주입받음
  • 컨테이너가 의존성 그래프를 자동 해결

컨테이너 안의 Bean 들:
   ┌──────────────────────────┐
   │  BoardController (Bean)  │
   │  BoardService (Bean)     │
   │  BoardMapper (Bean)      │
   │  ... 등                  │
   └──────────────────────────┘

IoC 의 효과

항목변화
결합도↓ — 인터페이스에만 의존
유연성↑ — 부품 교체 시 클래스 수정 없음
테스트 용이성↑ — Mock 으로 쉽게 갈아끼움
코드 간결화new 가 사라짐
싱글톤 관리자동 — 메모리 효율

왜 「역전」 인가

기존 흐름 (개발자가 제어) 개발자 코드 → new 로 객체 생성 → 메서드 호출 → 다른 객체도 new (개발자가 모든 결정) IoC 흐름 (컨테이너가 제어) 컨테이너 → 객체 생성·등록 → 의존성 분석 → 필요한 곳에 주입 개발자 → 「쓸 수 있는 객체를 받음」 (컨테이너가 결정의 주체)

구현 방법 — IoC 의 종류

방식설명
DI (의존성 주입)의존 객체를 외부에서 주입 ⭐
Service Locator레지스트리에서 찾아서 사용
Template Method틀이 흐름 통제, 변경 부분만 구현

👉 Spring 의 IoC 는 주로 DI 로 구현. 다음 차시에서 자세히.

실험 — 수동 IoC 흉내


// 우리가 컨테이너 역할을 함
public class App {
    public static void main(String[] args) {
        // 부품 결정
        MessageSender sender = new GmailSender();   // 또는 KakaoSender

        // 주입
        OrderService service = new OrderService(sender);

        service.order();
    }
}

👉 OrderService 코드는 한 줄도 수정 X. 부품 결정은 main 메서드(외부) 가.

다음 차시 — Spring 의 자동 IoC


@Service
public class OrderService {
    @Autowired
    private MessageSender sender;    // 컨테이너가 자동 주입
}

👉 main 에서 직접 주입하지 않아도 — Spring 컨테이너가 자동으로.

🔄 Before / After

전 차시 끝

강한 결합의 답답함을 체감했다.

이번 차시 끝

「제어권을 외부 컨테이너에 위임」 의 발상을 안다. Bean 이라는 용어 이해.

이번 차시의 데이터 흐름

Spring 컨테이너
Bean 자동 생성·관리
우리 코드에 주입
「누가 객체를 만들어주는지」 — 컨테이너가 등장

정리

오늘 들고 가는 것

  • IoC = 객체 제어권을 외부에 위임
  • 비유: 택시 뒷좌석
  • Spring 컨테이너 = IoC 의 실행자
  • Bean = 컨테이너가 관리하는 객체
  • 다음 차시 — DI 로 실제 코드 작성