웹개발/SpringBoot

IoC(제어의 역전),DI(의존성 주입)

bergerac 2025. 5. 19. 09:11

전통적인 자바 방식

class Book1 {
    private String title;

    public Book1(String title) {
        this.title = title;
    }

    public String getTitle() {
        return this.title;
    }
}

class BookStore1 {
    private Book1 book;

    public BookStore1() {
        this.book = new Book1("Spring Boot 기초");
    }

    public void displayBook() {
        System.out.println("Book: " + book.getTitle());
    }
}

위 코드는 우리가 흔히 짜는 평범한 Java 클래스다. BookStore1이 생성될 때 Book1 객체도 함께 직접 생성한다. 여기서 문제가 되는 건 Book1 클래스가 변경되면 BookStore1도 같이 바뀌어야 한다는 점이다. 즉, 두 클래스의 결합도가 높다.

이런 구조에서는 다음과 같은 문제가 생긴다:

  • 유닛 테스트 작성이 어렵다 (모킹 불가)
  • 기능이 바뀌면 여러 클래스에 영향을 줘야 함
  • 확장성이 떨어짐

IoC와 DI를 적용한 스프링 방식

@Component
class Book2 {
    private String title;

    public Book2() {
        this.title = "스프링 기초";
    }

    public String getTitle() {
        return this.title;
    }
}

@Component
class BookStore2 {
    private Book2 book;

    @Autowired
    public BookStore2(Book2 book) {
        this.book = book;
    }

    public void displayBook() {
        System.out.println("Book2: " + book.getTitle());
    }
}

여기서는 Book2와 BookStore2 모두 @Component 애너테이션을 통해 스프링 컨테이너에 등록된다. 그리고 @Autowired를 통해 의존성 주입(DI) 이 일어난다.

개발자는 new Book2()를 직접 호출하지 않는다. 대신 스프링 컨테이너가 Book2 객체를 생성하고 BookStore2에 넘겨준다. 이게 바로 제어의 역전(IoC) 이다. 객체 생성과 흐름 제어의 책임이 개발자에서 스프링 컨테이너로 넘어간 것이다.

핵심 개념 정리

1. 제어의 역전 (IoC)

제어의 역전은 객체의 생성, 연결, 생명주기 관리를 개발자가 직접 하지 않고, 외부의 컨테이너가 제어하도록 넘기는 것이다. 이로 인해 코드 구조는 훨씬 유연해지고, 객체 간의 결합도는 낮아진다.

2. 의존성 주입 (DI)

DI는 객체가 자신의 의존성을 직접 생성하는 게 아니라, 외부에서 주입받는 구조를 의미한다. 스프링에서는 생성자 주입, 필드 주입, 세터 주입이 가능하다.

그 중에서도 가장 추천되는 방식은 생성자 주입이다. final 필드를 활용해 불변성을 유지할 수 있고, 테스트와 유지보수에도 유리하다.

스프링 빈(Bean)과 컨테이너

  • 스프링 컨테이너: 모든 객체의 생명 주기를 관리하고 의존성을 주입해주는 핵심 엔진이다.
  • 빈(Bean): 컨테이너가 관리하는 객체. 클래스명에서 첫 글자를 소문자로 바꿔서 관리된다. (예: Book2 → book2)

빈을 등록하는 대표적인 애너테이션은 아래와 같다:

  • @Component: 일반적인 컴포넌트 등록
  • @Service: 서비스 계층의 빈 등록 (내부적으로 @Component 포함)
  • @Repository: 데이터 접근 계층 빈 등록
  • @Controller: 웹 컨트롤러 등록

'웹개발 > SpringBoot' 카테고리의 다른 글

Jpa Repository  (0) 2025.05.22
ORM (Object-Relational Mapping)  (4) 2025.05.21
SpringBoot 활용  (0) 2025.05.20
서블릿(Servlet)vs 스프링부트(SpringBoot)  (1) 2025.05.18
HTTP 통신  (0) 2025.05.17