어제 오늘 내일

[Spring Boot 입문 - 2] 자바 개발자의 필수템, IoC와 DI 완벽 이해하기 본문

IT/SpringBoot

[Spring Boot 입문 - 2] 자바 개발자의 필수템, IoC와 DI 완벽 이해하기

hi.anna 2026. 2. 10. 18:35

안녕하세요! 지난 시간에는 Spring과 Spring Boot의 차이점에 대해 알아봤습니다.

오늘은 스프링을 이해하는 데 가장 중요한 핵심 개념 두 가지를 이야기해보려고 합니다.

바로 IoC(제어의 역전)DI(의존성 주입)입니다.

이름만 들어도 벌써 머리가 아프시다구요? 걱정 마세요. 어려운 코드가 아니라 아주 쉬운 '상황극'으로 이해시켜 드리겠습니다.

 

1. 내가 다 해야 해? (기존의 방식)

우리가 평범한 자바 코드를 짤 때를 생각해 봅시다. 여러분이 '치킨 가게' 사장님(개발자)입니다.

치킨을 튀기려면 '닭'이 필요하겠죠? 그래서 여러분은 가게를 열 때마다 직접 양계장에 가서 닭을 사옵니다.

public class ChickenShop {
    // 사장님이 직접 닭을 구해옴 (new 사용)
    private Chicken chicken = new Chicken();

    public void cook() {
        chicken.fry();
    }
}

 

이 방식의 문제는 무엇일까요?

  1. 사장님이 너무 바쁩니다. 요리도 해야 하는데 재료 구하는 것까지 신경 써야 합니다.
  2. 변경이 어렵습니다. 만약 손님이 "오리 고기로 튀겨주세요"라고 하면? new Chicken() 코드를 지우고 new Duck()으로 코드를 다 뜯어고쳐야 합니다.

즉, 개발자(사장님)가 객체(재료)의 생성과 관리를 모두 '제어'하고 있는 상태입니다.

 

2. IoC (Inversion of Control): 제어의 역전

그런데 어느 날, 유능한 '알바생(Spring)'을 고용했습니다. 이제 상황이 바뀝니다.

사장님: "야, 나 요리해야 되니까 네가 알아서 재료 좀 준비해 놔."
알바생(Spring): "네, 제가 다 사다가 냉장고에 넣어둘게요. 사장님은 요리만 하세요."

이제 재료를 구하고 관리하는 주도권(제어권)이 사장님에게서 알바생에게로 넘어갔습니다. 이것이 바로 제어의 역전(IoC)입니다.

  • 기존: 개발자가 직접 new 연산자로 객체를 생성함.
  • Spring: 스프링 컨테이너(알바생)가 객체를 대신 생성하고 관리해 줌.

이제 사장님은 닭이든 오리든 신경 쓸 필요 없이, 알바생이 주는 대로 요리만 하면 됩니다.

 

3. DI (Dependency Injection): 의존성 주입

그럼 DI는 뭘까요? 알바생이 준비한 재료를 사장님에게 건네주는 행위 그 자체입니다.

사장님: "나 이제 요리할 건데 재료 좀 줘볼래?"
알바생(Spring): (닭을 쓱 건네주며) "여기 주입(Injection)해 드렸습니다."

코드로 보면 이렇게 바뀝니다.

public class ChickenShop {
    private Chicken chicken;

    // 생성자를 통해 외부(알바생)에서 재료를 받아옴
    public ChickenShop(Chicken chicken) {
        this.chicken = chicken;
    }

    public void cook() {
        chicken.fry();
    }
}

 

보세요. new Chicken()이 사라졌죠?
가게 내부에서 닭을 만드는 게 아니라, 외부에서 누군가가 닭을 쏙 넣어주는(주입하는) 구조가 되었습니다.

이것이 바로 의존성 주입(DI)입니다.

  • 의존성: ChickenShopChicken이 없으면 요리를 못함 (의존 관계).
  • 주입: 외부(스프링)에서 이 의존하는 객체를 넣어줌.

 

4. 그래서 뭐가 좋은 건데?

이 어려운 걸 왜 쓸까요? 이유는 딱 하나, "편하고 유연하기 때문"입니다.

1) 코드 변경이 쉬워집니다.
손님이 "오리 고기로 바꿔주세요!"라고 해도 사장님(ChickenShop 클래스)은 코드를 고칠 필요가 없습니다. 알바생(Spring 설정)에게 "야, 닭 말고 오리로 준비해 놔"라고만 하면, 알바생이 알아서 오리를 주입해 줄 테니까요.

2) 테스트하기 좋습니다.
진짜 닭 대신 '모형 닭'을 주입해서 요리 연습(테스트)을 해볼 수도 있겠죠?

 

5. 스프링에서 실제로 쓰는 모습

나중에 배우겠지만, 실제 스프링 부트 코드에서는 이렇게 보게 될 겁니다.

@Service // 1. 스프링아, 이건 네가 관리해(Bean 등록)
public class ChickenService {

    private final ChickenRepository chickenRepository;

    // 2. 생성자가 하나면 스프링이 알아서 DI(주입) 해줌
    public ChickenService(ChickenRepository chickenRepository) {
        this.chickenRepository = chickenRepository;
    }
}
  • @Service: 스프링(알바생)에게 "이거 네가 관리해"라고 명찰을 달아주는 겁니다. (이렇게 관리되는 객체를 'Bean'이라고 부릅니다.)
  • 생성자: 스프링이 미리 만들어둔 RepositoryService에 쏙 주입해 줍니다.

 

요약 정리

  1. IoC (제어의 역전): new를 써서 내가 직접 만들지 않고, 스프링에게 객체 관리를 맡기는 것 (사장님이 알바생에게 잡일을 위임함).
  2. DI (의존성 주입): 스프링이 관리하던 객체를 필요한 곳에 알아서 넣어주는 것 (알바생이 사장님 손에 재료를 쥐여줌).
  3. 결과: 개발자는 객체 생성이나 관리에 신경 쓰지 않고, 핵심 로직에만 집중할 수 있게 됨!

개념이 좀 잡히셨나요?
이 두 가지만 이해해도 스프링의 절반은 넘으신 겁니다!

다음 시간에는 이론은 이제 그만!
IntelliJ를 설치하고 실제로 Spring Boot 프로젝트를 만들어보는 시간을 갖겠습니다.

5분이면 나만의 웹 서버를 띄울 수 있습니다.

다음 편에서 만나요! 👋

반응형
Comments