[Spring] IOC/DI

이연우·2025년 7월 25일

TIL

목록 보기
44/100

🔁 IOC(제어의 역전, Inversion Of Control)란?

  • 객체의 생성과 제어 권한을 개발자가 아닌 Spring Container가 가져가는 개념
  • 직접 new로 만들지 않고 Spring이 대신 만들어서 관리

📚 IOC의 역할

👨‍🍳 비유: 셰프가 요리 재료를 준비

  • 기존 방식: 개발자가 직접 재료(객체)를 골라 요리(로직)를 실행함
  • IoC 방식: 셰프(Spring)가 알아서 재료를 준비하고, 필요한 곳에 제공함
직접 제어 (전통적)제어 역전 (IOC)
개발자가 객체 생성Spring이 생성
개발자가 의존성 주입Spring이 자동으로 주입

🔧 IOC 개념 요약

  • 객체의 생성, 생명주기, 소멸을 Spring이 관리
  • 객체 간의 결합도를 낮추고, 코드의 유연성이 높아짐
  • IoC는 기본 개념, DI는 이를 구현하는 방법 중 하나

🤝 DI (Dependency Injection, 의존성 주입)란?

  • 객체 간의 의존성을 Spring이 대신 연결해주는 기술
  • 개발자가 직접 new 하지 않고, 필요한 객체를 Spring이 주입해 줌

📚 DI의 역할

🍳 비유: 셰프가 재료를 요리사에게 전달

  • 요리사(서비스)는 요리에 필요한 재료(리포지토리)를 직접 찾지 않고,
    셰프(Spring Container)가 필요한 재료를 자동으로 전달

📌 DI가 필요한 이유

  • 직접 객체를 생성하면 코드 간 결합도가 높아짐
  • 새로운 구현체가 생기면 클라이언트 코드까지 변경해야 함
  • Spring이 대신 객체를 만들어서 주입하면 → OCP, DIP 준수

🗂️ DI 방식 요약

방식예시특징
생성자 주입@Autowired 생성자 사용가장 권장됨
필드 주입필드 위에 @Autowired테스트 불편, 권장 안 함
세터 주입@Autowired 세터 메서드선택적 주입에 적합

🧩 IOC/DI 정리 요약

항목설명
IOC (제어의 역전)객체 생성/관리를 Spring이 대신함
DI (의존성 주입)필요한 객체를 자동으로 주입함
목적코드의 결합도↓, 유연성↑, 재사용성↑
구현 방식생성자 주입, 필드 주입, 세터 주입 등

✅ IOC/DI의 장점

장점설명
유연한 구조구현체만 바꿔도 코드 변경 없음
유지 보수 용이의존 객체 교체가 쉬움
테스트 편리Mock 객체 등으로 대체 가능
모듈화 용이책임 분리가 명확해짐

❌ 직접 객체를 관리할 경우 (전통적 방식)

MyRepository repo = new MyRepositoryImpl(); // 직접 생성
MyService service = new MyServiceImpl(repo); // 강한 결합

MyRepositoryImplV2로 변경 시 main() 코드를 직접 고쳐야 함
클래스 간 결합도가 높아짐 → 유지 보수 어려움

✅ Spring이 객체를 주입할 경우 (IOC + DI 적용)

@Service
public class MyIocService implements MyService {

    private final MyRepository myRepository;

    @Autowired // 생성자 주입
    public MyIocService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}
@Repository
public class MyIocRepository implements MyRepository {
    public void queryDatabase() {
        System.out.println("쿼리 실행");
    }
}
@ComponentScan(basePackages = "com.example")
public class MyIocApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyIocApp.class);
        MyService service = context.getBean(MyService.class);
        service.doSomething();
    }
}

MyIocRepositoryV2가 새로 생겨도 서비스 코드는 변경 없이 교체 가능
→ Bean으로 등록만 바꾸면 됨 (ex. @Primary 사용 등)


🎯 한눈에 보는 핵심 흐름

  1. 개발자는 인터페이스만 정의

  2. 구현체는 @Component, @Service, @Repository로 등록

  3. Spring Container가 자동으로 생성/주입

  4. 코드는 변화 없이 실행됨 (확장성 ↑)

0개의 댓글