개발

[React.js, 스프링부트, AWS로 배우는 웹 개발] 2장 - 의존성 주입

jih0ssang 2024. 7. 18. 17:49

스프링 프레임워크와 의존성 주입

의존성 주입 (DI, Dependency Injection)

  • 객체가 다른 객체에 의존하는 것을 명시적으로 선언하고 외부에서 해당 객체의 인스턴스를 주입하는 설계 패턴

의존성 

[생성자 내부에서 오브젝트 초기화]

public class TodoService {
  private final FileTodoPersistence persistence;
  
  public TodoService() {
    this.persistence = new FileTodoPersistence();
  }
  
  public void create(...){
  ...
  persistence.create(...);
  }
}

 

TodoService 클래스는 Todo 목록을 관리하는 기능이다.

FileTodoPersistence는 파일에 Todo 목록을 저장할 수 있도록 도와주는 클래스이다.

따라서 TodoService는 FileTodoPersistence 없이는 제 기능을 하지 못하므로 의존한다.

FileTodoPersistence에 의존하는 TodoService가 FileTodoPersistence 오브젝트를 생성하고 관리한다.

 

향후 데이터베이스에 저장하는 것으로 바뀌어서 FileTodoPersistence 대신 DatabaseTodoPersistence로 구현해야 할 때,

FileTodoPersistence에 의존하는 서비스가 100개 정도 생겼다면 100개의 클래스를 돌아다니면서 수정해야 한다.

 

 

유닛 테스트(Unit Test)
- 코드의 작은 부분(주로 개별 함수 또는 메서드)이 기대한 대로 동작하는지 검증하는 테스트
- 각각의 유닛 테스트는 독립적으로 수행되어야 하고 다른 테스트에 의존해서는 안됨

(Mock 클래스로 보통 의존성 주입 해결)

 


이런 문제를 해결하는 것이 의존성 주입이다.
의존성 주입이란 이 클래스가 의존하는 다른 클래스들을 외부에서 주입시킨다는 뜻이다.
이를 구현하는 방법에는 다음이 있다.

  1. 생성자를 이용해 주입하는 방법
  2. Setter를 이용해 주입하는 방법

 

1. 생성자를 이용해 주입하는 방법

[생성자를 이용해 의존성 주입, 서비스 코드]

public class TodoService {
  private final ITodoPersistence persistence; // 인터페이스
  
  public TodoService(ITodoPersistence persistence) {
    this.persistence = persistence;
  }
  
  public void create(...){
    ...
    persistence.create(...);
    }
  }

한 오브젝트가 의존하는 오브젝트를 생성하는 것이 아니라 외부에서 넘겨받는 것을 의존성 주입이라고 한다.

TodoService는 오브젝트 생성할 때 FileTodoPersistence 이 아니라  ITodoPersistence 에게 넘겨주며 의존성 주입한다.

FileTodoPersistence이 직접적으로 하면 의존성 문제가 있으므로

FileTodoPersistence 의 인터페이스 역할인 ITodoPersistence에게 의존성을 주입하는 것이다.

 

TodoService의 persistence 값은 FileTodoPersistence가 아니라,

FileTodoPersistence의 인터페이스인 ITodoPersistence의 persistence 값을 대입한다.

 

ITodoPersistence 는 인터페이스이다.

 

 

[생성자를 이용해 의존성 주입, 메인 코드]

public static void main(String[] args){
  ITodoPersistence persistence = new FileTodoPersistence();
  TodoService service = new TodoService(persistence);
}

ITodoPersistence 는 FileTodoPersistence의 인터페이스이다.

TodoService 에게 FileTodoPersistence 대신 ITodoPersistence를 넘겨주어, 생성자를 생성하도록 한다.

 

 

 

2. Setter를 이용해 주입하는 방법

생성자 대신 Setter를 만든다.

 

[Setter를 이용해 의존성 주입, 서비스 코드]

public class TodoService {
  private final ITodoPersistence persistence;
  
  public void setITodoPersistence(ITodoPersistence persistence) {
    this.persistence = persistence;
  }
}

setITodoPersistence 메서드를 생성하여  ITodoPersistence 인터페이스를 매개변수로 입력받아

TodoService 의 persistence 값에 ITodoPersistence 인터페이스의 persistence 값을 대입하는 것이다.

 

 

[Setter를 이용해 의존성 주입, 메인 코드]

public static void main(String[] args){
    ITodoPersistence persistence = new FileTodoPersistence();
    TodoService service = new TodoService();
  service.setITodoPersistence(persistence);
}

메인 메서드에서 사용할 때, 오브젝트를 초기화한 후, Setter 메서드를 통해 오브젝트를 생성한다.

 

IoC 컨테이너는 의존성 주입 컨테이너이다.

관리할 오브젝트가 많아지면서 의존성 주입 컨테이너의 필요성이 높아진다.

 

스프링 프레임워크를 이용하면 어노테이션이나 XML 또는 자바 코드를 이용해 오브젝트(빈bean 이라고 부름) 간 의존성을 명시할 수 있다.

애플리케이션 시작 시 스프링 프레임워크의 IoC 컨테이너라는 자바 오브젝트를 이용해 오브젝트를 생성 및 관리해준다.