본문 바로가기
공부방

[TIL 06/20] IoC, DI, ApplicationContext

by hseong 2023. 6. 20.

IoC

애플리케이션의 제어 흐름을 직접 관리하는 것이 아니라 외부에서 관리하는 것을 제어의 역전(Inversion of Control)이라 한다.

  • 객체가 자신이 사용할 객체를 선택하거나 생성하지 않는다.
  • 생성한 코드에서는 OrderService가 어떤 OrderRepository를 사용할지, 어떤 ItemService를 사용할지 직접 선택하거나 객체를 생성하지 않는다. OrderService는 묵묵히 자신의 로직을 실행하는 역할만을 담당한다.
  • 객체를 만드는 책임은 오롯이 설정 파일로써 작성한 AppConfig가 가지고 있게 된다. 이것이 제어의 역전이 발생한 상황이고 이러한 IoC를 가능하게 하는 공간을 IoC 컨테이너라고 부른다.
  • IoC 컨테이너에서 개별 객체간의 의존 관계 설정이 이루어지고 객체의 생성, 파괴와 같은 라이프사이클을 책임진다.

DI

애플리케이션의 런타임에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버 사이에 실제 의존관계에 연결 되는 것을 의존관계 주입(Dependency Injection)이라 한다.

  • 객체 인스턴스를 생성하고, 그 참조값을 전달해서 연결된다.
  • 의존관계 주입을 사용하면 클라이언트 코드의 변경 없이 호출하는 대상의 타입 이스턴스를 변경 가능하다.
  • IoC를 구현하는 패턴이라고 볼 수 있다.
  • 스프링은 의존성을 주입하기 위한 방식으로 생성자 주입, 세터 주입 등을 지원하며 생성자 주입을 추천하고 있다.

ApplicationContext

  • 일종의 IoC 컨테이너이며 스프링 컨테이너라 불리는 인터페이스이다.
  • 개별 객체들의 의존관계 설정이 자동으로 이루어지고 등록된 객체의 라이프사이클을 관리한다.
  • IoC 컨테이너에 클래스들을 등록할거라고 알려주면 객체의 라이프사이클을 관리하며 인스턴스를 만들어준다.
  • Bean은 IoC 컨테이너에 의해서 관리되는 객체를 말한다.
  • BeanFactory
    • 스프링 컨테이너의 최상위 인터페이스이다.
    • 스프링 빈을 관리하고 조회하는 역할을 담당한다.
    • getBean()을 제공한다.
  • ApplicationContext
    • BeanFactory를 상속받으며 부가기능을 제공한다.
    • 메시지 소스를 활용한 국제화 기능
    • 환경변수
    • 애플리케이션 이벤트
      • 이벤트를 발행하고 구독하는 모델을 지원한다.
    • 편리한 리소스 조회
      • 파일, 클래스패스 등에서 리소스를 편리하게 조회한다.
  • Configuration metadata
    • 이 메타데이터를 가지고 IoC 컨테이너에 의해 관리되는 객체들을 생성하고 구성한다.
    • XML 기반 또는 자바 파일 기반으로 작성 가능하다.
      • GenericXmlApplicationContext를 사용하면 XML 설정 파일을 넘기면 된다.
      • 애노테이션 기반 자바 코드 설정을 사용할 경우 AnnotationConfigApplicationContext 구현체에 자바 코드로 된 설정 정보를 넘기면 된다.
  • BeanDefinition
    • Configuration metadata를 포함하며 이로부터 BeanDefinition을 만든다.
    • 스프링 컨테이너는 자바 코드인지, XML 코드인지 알 필요 없이 오직 BeanDefinition만 알면 된다.
    • 이 메타 정보를 기반으로 스프링 빈을 생성한다.
  • 스프링 컨테이너는 @Configuration이 붙은 클래스를 설정 정보로 사용한다. 해당 클래스의 @Bean이 붙은 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다.
  • @Configuration public class AppConfig { @Bean public OrderService orderService(OrderRepository orderRepository) { return new OrderService(orderRepository); } @Bean public OrderRepository orderRepository() { return new OrderMemoryRepository(); } }
  • 스프링 빈은 @Bean이 붙은 메서드의 명을 스프링 빈의 이름으로 사용한다.
  • 스프링 빈은 applicationContext.getBean() 메서드를 사용해서 찾을 수 있다.
  • AnnotaionConfigApplicationContext 생성 시 AppConfig를 설정 정보로써 넘겨주면 이를 토대로 스프링 컨테이너에 스프링 빈을 등록하고 의존관계를 주입한다.