1.7 의존관계 주입(DI)

의존관계란?

A라는 클래스가 B클래스 내 메소드 C를 사용하고 있다고 가정해보자. 이 때에는 A가 B를 의존한다고 칭한다. B안에 있는 메소드 C의 기능이 변경되거나, 추가될 경우 A에게 영향이 간다. 이렇듯 B의 변화가 A에 영향을 받고 있을 경우에는 A와 B간에 의존관계가 있다고 할 수 있다.

의존관계 주입이란?

의존관계 주입(Dependency Injection)이란 오브젝트 레퍼런스를 외부로부터 제공(주입)받고 이를 통해 여타 오브젝트와 다이내믹하게 의존관계가 만들어지는 것을 말한다. 의존관계 주입은 아래 세 가지 조건을 충족해야 한다.

  • 클래스 모델 혹은 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스에만 의존하고 있어야 한다.
  • 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다.
  • 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.

의존관계 주입의 핵심은 설계 시점에는 알지 못했던 두 오브젝트의 관계를 맺도록 도와주는 제3의 존재가 있다는 것이다. 이 제3의 존재는 전략패턴에서 말하는 클라이언트라고 말할 수도 있고, 팩토리 클래스 일 수도 있다.

주입

주입이라는 건 외부에서 내부로 무엇인가를 넘겨줘야 하는 것을 말한다. 자바에서 오브젝트에 무엇인가를 넣어준다는 개념은 메소드를 실행하면서 파라미터로 오브젝트의 레퍼런스를 전달해주는 방법 뿐이다. 가장 쉬운 방법은 생성자이다(물론 setter나 일반 메소드로도 가능하다).

실제 오브젝트가 아닌 인터페이스를 통해 의존관계를 형성한다면 ?

인터페이스를 구현한 클래스가 다른 것으로 바뀌거나, 내부에서 사용하는 메소드에 변화가 생겨도 클라이언트(실제 해당 오브젝트를 주입받는 오브젝트)에는 영향이 가지 않는다. 인터페이스 구현 클래스와의 관계는 느슨해지면서 변화에 영향을 덜 받는 상태가 된다.


의존관계 검색

의존관계를 맺는 방법이 외부로부터의 주입이 아니라 스스로 검색을 이용하는 경우 의존관계 검색(dependency lookup)이라고 한다. 자신이 필요로 하는 의존 오브젝트를 능동적으로 찾는다.
스프링 IoC컨테이너인 애플리케이션 컨텍스트는 getBean()이라는 메소드를 제공하며, 바로 이 메소드가 의존관계 검색에 사용된다.

public UserDao {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
    this.connectionMaker = context.getBean("connectionMaker", ConnectionMaker.class);
}

위와 같이 의존관계 검색 방법은 코드 안에 오브젝트 팩토리 클래스나 스프링 API가 나타나 조금 더 깔끔해보인다.

의존관계 주입과 검색의 차이점?

의존관계 주입시에는 주입받는 오브젝트와 주입하려는 오브젝트 모두 컨테이너가 만드는 빈 오브젝트여야 하나, 의존관계 검색에서는 검색하는 오브젝트 자신이 스프링의 빈일 필요가 없다.


의존관계 주입(DI)의 주요 장점

  • 기능 구현의 교환
    • DB연결을 담당하는 오브젝트를 DI하는 방식으로 구성되어 있지 않고 독립적으로 관리되고 있다면, 개발<->운영 DB구성을 바꾸려면 이 connection을 관리하는 오브젝트를 일일히 찾아 바꿔주어야 한다. 하지만, DI하는 방식으로 관리되어 있다면 오직 DB연결을 담당하는 코드 딱 한 구간에만 변경하면 된다.
  • 부가기능 추가
    • 만일 DAO가 DB를 얼마나 많이 연결해서 사용하는지 파악하고 싶다고 해보자. DI가 적용되지 않았다면 DB연결하는 메소르를 호추라는 부분에 새로 카운터를 증가시키는 코드를 넣어야 할까? 이렇게 된다면 위 기능 구현의 교환 때 생겼던 문제처럼 엄청난 반복성, 비효율적인 코딩을 반복하게 될 것이고 스프링에서 지향하는 ‘단일책임의 원칙’을 위배하게 된다. DI컨테이너에서는 DAO와 DB커넥션을 만드는 오브젝트 사이에 연결횟수를 카운팅하는 오브젝트를 하나 더 추가하는 것 만으로도 해결이 가능하다 ! (Amazing)

토비의 스프링 3.1을 토대로 작성하였으나, 개인적인 의견이 담겨있어 부정확한 내용이 작성되었을 수 있습니다. 코멘트로 많은 의견 부탁드립니다 :)


oksusutea's blog

꾸준히 기록하려고 만든 블로그