직관적으로 간추린 토비의스프링 1장.3 - IoC(제어의 역전)

디퐁·2022년 12월 25일
0
post-thumbnail

일러두기

  • 토비의스프링3.1 Vol.1을 읽고 정리한 글입니다.
  • 책을 이미 읽으신 분이 빠르게 훑으며 복습하는 용도로 보시면 좋을 것 같습니다.
  • 임의로 핵심만 간추렸습니다. 책과 설명하는 순서가 바뀌거나 장/절 목차 이름이 바뀌거나 아예 빠진 내용이 많습니다.

1 IoC(제어의 역전)

제어의 역전(IoC; Inversion of Control)

오브젝트 팩토리

UserDaoTest의 개선 ✨

  • 어떤 ConnectionMaker를 사용할지 결정하는 기능을 엉겁결에 떠맡았다
  • 원래 UserDaoTest는 UserDao의 기능이 잘 동작하는지 테스트하려고 만든 것인데
    • 지금은 또 다른 책임까지 떠맡고 있다

UserDao에서 분리시킬 기능

  • UserDao와 ConnectionMaker 구현 클래스의 오브젝트 만들기
  • 그렇게 만든 두 오브젝트 관계 맺어주기

팩토리

  • 분리시킬 기능을 담당할 클래스
  • 객체의 생성 방법을 결정하고 만들어진 오브젝트를 돌려주는 역할
    • 이런 오브젝트를 팩토리라고 부른다

설계도로서의 팩토리

  • UserDao: 핵심적인 데이터 로직을 맡는다
  • ConnectionMaker: 핵심적인 기술 로직을 맡는다
  • DaoFactory
    • UserDao, ConnectionMaker 두 오브젝트를 구성하고 그 관계를 정의하는 책임을 맡는다
    • 컴포넌트의 구조와 관계를 정의하는 설계도 같은 역할을 하는 것이다

생성할 DAO가 많아지면 발생하는 문제

  • 중복이 발생한다
    • ConnectionMaker 구현 클래스의 오브젝트를 생성하는 코드의 중복

오브젝트 생성 코드의 분리 ✨

  • 메서드로 분리해서 중복을 제거해준다.

제어권의 이전을 통한 제어의 역전

제어의 역전이란

  • 프로그램의 제어 흐름 구조가 뒤바뀌는 것
  • 일반적 흐름
    • 사용하는 쪽에서 제어하는 구조
    • 프로그램이 시작되고
    • 사용할 오브젝트를 결정하고
    • 결정한 오브젝트를 생성하고
    • 만들어진 오브젝트에 있는 메서드를 호출하고
    • 그 메서드 안에서 다음에 사용할 것을 결정하는 식
  • 제어의 역전 시 흐름
    • 자신이 사용할 오브젝트를 스스로 선택하지 않는다
    • 생성하지도 않는다
    • 자신도 어떻게 만들어지고 어디서 사용되는지 알 수 없다
    • 모든 제어 권한을 자신이 아닌 다른 대상에게 위임한다!

제어의 역전의 예시

  • 서블릿
  • 템플릿 메서드 패턴
    • 추상메서드 getConnection
    • 이 메서드가 언제 어떻게 사용될지 자신은 모른다
  • 프레임워크
    • 라이브러리
      • 동작하는 중에 필요한 기능이 있을 때 능동적으로 라이브러리를 사용한다
    • 프레임워크는 거꾸로 프레임워크가 애플리케이션 코드를 사용한다
      • 프레임워크 위에 개발한 클래스를 등록
      • 프레임워크가 흐름을 주도하는 중
      • 개발자가 만든 코드를 사용하도록 만드는 방식
  • DaoFactory
    • Connection의 구현 클래스를 결정하고 오브젝트를 만드는 제어권을 가진다

제어의 역전을 위해 필요한 것

  • 컴포넌트의 생성, 관계설정, 사용, 생명주기 관리 등을 관장하는 존재가 필요하다
    • IoC 컨테이너, IoC 프레임워크라고 부른다
  • 스프링이 바로 IoC를 극한까지 적용하고 있는 프레임워크다.
  • 우리가 만든 DaoFactory는 가장 단순한 IoC 컨테이너 또는 IoC 프레임워크라고 불릴 수 있다

2 스프링 IoC

애플리케이션 컨텍스트=빈 팩토리

  • 이것이 스프링의 핵심을 담당한다
  • DaoFactory가 하는 일을 좀 더 일반화한 것이다

오브젝트 팩토리를 이용한 스프링 IoC

  • 스프링이 제어권을 가지고
    • 직접 만들고
    • 관계를 부여하는 오브젝트
  • 제어의 역전이 적용된 오브젝트

빈 팩토리

  • 빈의 생성/관계설정 등의 제어를 담당하는 IoC 오브젝트

애플리케이션 컨텍스트

  • IoC 방식을 따라 만들어진 일종의 빈 팩토리

빈 팩토리 vs 애플리케이션 컨텍스트 용어 차이

  • 기본적으로 같은 대상을 가르킨다고 봐도 무방하다.
  • 어디에 더 중점을 둬서 말하느냐의 차이다
  • 빈 팩토리
    • 빈을 생성하고, 관계를 설정하는
    • IoC의 기본 기능에 초점을 맞추어 부르는 용어
  • 애플리케이션 컨텍스트
    • 애플리케이션 전반에 걸쳐 모든 구성요소의 제어작업을 담당하는
    • IoC 엔진이라는 의미를 좀 더 부각하여 부르는 용어

DaoFactory를 스프링 빈 팩토리로 등록하기 ✨


  • 아직까지는 오히려 좀 더 번거로운 준비 작업과 코드가 필요하다
  • 아직까지는 DaoFactory와 기능적으로 다를 바 없다

애플리케이션 컨텍스트

구조

  • ApplicationContext 인터페이스와
  • BeanFactory 인터페이스를 상속한다
    • 일종의 빈 팩토리인 셈이다

동작방식

  • IoC를 적용해 관리할 모든 오브젝트에 대한 생성과 관계설정을 담당한다
  • 생성정보와 연관관계 정보를 별도의 설정정보를 통해 얻는다
    • xml, 어노테이션 등
  • 때로는 외부의 오브젝트 팩토리에 그 작업을 위임한다
    • 바로 위에서 DaoFactory에 위임하게끔 하는 설정을 해봤다.

@Configuration이 붙은 DaoFactory

  • 애플리케이션 컨텍스트가 활용하는 IoC 설정정보로 쓰인다
  • @Bean이 붙은 메서드의 이름을 가져와 구성할 빈의 목록을 만든다

애플리케이션 컨텍스트 사용의 장점

  • 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다
  • 종합 IoC 서비스를 제공해준다
    • 오브젝트가 만들어지는 방식을 다르게 가져가기
      • 시점과 전략에 따라
    • 오브젝트를 효과적으로 활용할 수 있는 다양한 기능 제공
      • 자동생성, 오브젝트에 대한 후처리, 정보의 조합
      • 설정 방식의 다변화, 인터셉팅
  • 빈을 검색하는 다양한 방법을 제공한다
    • getBean()
      • 빈의 이름으로 빈 찾기
      • 타입으로 빈 검색하기
      • 특정 어노테이션이 달린 빈 검색하기

3 IoC와 의존관계 주입

IoC 컨테이너

  • 객체 생성/관계 맺어주는 등의 작업을 담당하는 기능을 일반화한 것

IoC라는 용어

  • 매우 느슨하게 정의돼서 폭넓게 사용되는 용어

의존관계 주입

  • 의존관계 주입(DI; Dependency Injection)
  • 스프링이 제공하는 IoC(제어의 역전)의 핵심을 짚어주는 용어
  • 스프링을 DI 컨테이너라고도 부른다

의존관계

  • 두 개의 클래스 또는 모듈이 의존관계에 있다고 말할 때는 항상 방향성을 부여해줘야 한다
    • A -> B
  • 의존한다는 것은
    • B의 기능이 추가/변경되면
    • 그 영향이 A로 전달된다는 것
    • 대표적인 예
      • A에서 B 객체에 정의된 메서드를 호출해서 사용

UserDao의 의존관계

  • UserDao가 ConnectionMaker에 의존하고 있는 관계다
  • ConnectionMaker 인터페이스가 변하면 영향받는다
    • 하지만 인터페이스를 구현한 클래스에 의해서는 영향받지 않는다
    • = 느슨한 결합

의존관계 주입은

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

의존관계의 핵심

  • 설계 시점에는 알지 못했던 두 오브젝트의 관계를 맺도록 도와주는 제3의 존재
  • DaoFactory, IoC 컨테이너

UserDao의 의존관계 주입

  • 제3의 존재: DaoFactory가 DI를 해줌
    • 오브젝트의 생성, 초기화, 제공 등의 작업을 수행한다
    • DI 컨테이너라고 불러도 됨

의존성을 주입해줬다고 다 DI는 아니다

  • 다이나믹하게 구현 클래스를 결정해 제공받을 수 있어야 DI다
  • 특정 구현 클래스로 고정되어있다면 DI가 아니다
    • UserDao는 DConnectionMaker라는 특정 구현 클래스가 아닌
    • ConnectionMaker라는 인터페이스에 의존함으로써
    • ConnectionMaker 인터페이스를 구현한 여러 구현클래스들을 사용할 수 있다

장점

  • 결합도가 낮다
  • 변경을 통한 다양한 확장 방법에 자유롭다

의존관계 주입의 응용

기능 구현의 교환

  • 로컬 디비 -> 운영 디비 구현 클래스 교체가 간편하다
  • DAO 클래스의 코드를 수정할 필요 없이
  • DaoFactory의 빈 등록 코드만 변경하면 된다

부가기능 추가

  • DB 연결횟수 카운팅하는 기능을 추가하여 구현한 클래스
    • ConnectionMaker를 멤버변수로 가지고 counter 기능을 추가함
  • 위와 같이 부가기능을 추가하기도 간편하다

4 용어 정리

  • 스프링이 IoC 방식으로 관리하는 오브젝트
  • 관리되는 오브젝트(managed object)
  • 스프링이 직접 생성과 제어를 담당하는 오브젝트만을 빈이라 부른다

빈 팩토리

  • 스프링의 IoC를 담당하는 핵심 컨테이너
  • 빈을 등록하고, 생성하고, 조회하고, 반환한다.

애플리케이션 컨텍스트

  • 빈 팩터리를 확장한 IoC 컨테이너
  • 빈 팩터리에 각종 부가 서비스를 추가로 제공한다
  • 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함해서 이야기할 때 이 용어를 쓴다

설정 메타정보

  • IoC를 적용하기 위해 사용하는 메타정보
  • XML, 어노테이션 등

IoC 컨테이너

  • IoC 방식으로 빈을 관리하는 무언가를 말할 때 이 용어를 사용한다
    • 애플리케이션 컨텍스트
    • 빈 팩토리
  • 스프링 컨테이너, 컨테이너라고도 부른다.

스프링 프레임워크

  • IoC 컨테이너, 애플리케이션 컨텍스트를 포함해서
  • 스프링이 제공하는 모든 기능을 통틀어 말할 때 이 용어를 주로 사용한다
profile
Backend 취준생

0개의 댓글