Spring

[Spring] IoC

📝 작성 : 2020.07.10  ⏱ 수정 : 
728x90

IoC(Inversion of Control)

제어의 역전이란 뜻입니다. 초기에는 개발자가 객체를 생성하고 의존관계를 직접 설정하였는데 이를 제어라고 합니다. 이 제어라는 행동을 컨테이너라는 것에 맡기는 것을 제어권이 역전되었다고 합니다. IoC 구현방법에는 DL(Dependency Lookup), DI(Dependency Injection) 2가지가 있습니다.
우선, 일반적인 클래스 호출방식과 IoC를 이용한 클래스 호출 방식의 차이를 도식화하여 알아보고 IoC에 대해 좀 더 자세하게 알아보겠습니다.

클래스 호출 방식

가장 기본적인 클래스 호출 방식

클래스내에 선언, 구현이 다 있기 때문에 다양한 형태로의 변환이 불가능합니다.

인터페이스 호출 방식

구현클래스의 교체 등 다양한 변화가 가능하지만 구현클래스 교체시 호출클래스의 소스를 일부 수정해야 합니다.(부분적으로 종속적입니다.)

팩토리패턴을 이용한 클래스 호출 방식

팩토리가 구현클래스를 생성하므라 구현클래스 변경시 팩토리만 수정하면됩니다. 하지만 구현클래스에는 팩토리를 호출해야하는 소스가 들어감으로 팩토리에 의존적입니다.

IoC를 이용한 클래스 호출 방식

어떤 것에도 의존하지 않는 형태로 구성된 형태입니다. 실행 시점에서 클래스 간의 관계가 형성됩니다.

일반적인 제어권 vs 역전된 제어권

  1. 일반적인 제어권 : 자기가 사용할 의존성을 자기가 만들어서 사용합니다.
    public class ToyService {
    private ToyRepository toyRepository = new ToyRepository();
    }

2. IoC : 사용은 하지만 만들지는 않습니다. 누군가가 밖에서 관리해줍니다.
public class ToyService {
    private ToyRepository toyRepository;

    // 생성자를 통해 받아옵니다.
    public ToyService(ToyRepository toyRepository) {
        this.toyRepository = toyRepository;
    }
}

IoC 주요 용어

  • Bean : 스프링 컨테이너가 생성하고 관계를 만들고 사용을 제어하는 객체 즉, 스프링 컨테이너가 관리하는 모든 객체를 뜻 합니다.
  • BeanFactory : BeanFactory 인터페이스는 스프링 IoC컨테이너의 기능을 정의하는 인터페이스입니다. Bean의 생성, 의존관계 설정, 생명주기 관리 등의 기능을 제공합니다.
  • ApplicationContext : BeanFactory 인터페이스를 상속합니다. BeanFactory기능 외에 AOP, 메시지 처리, 이벤트 처리 등의 기능을 제공합니다. 특별한 경우가 아니면 이 ApplicationContext를 사용합니다.
  • (IoC) Container : IoC방식으로 Bean을 관리하는 의미에서 bean factory나 application context를 가리킵니다.

IoC 구현 방법

  1. DL(Dependency Lookup) : 의존성 검색
    Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용해 Bean을 Lookup하는 방식입니다.
    객체간 Decoupling을 해주는 장점이 있지만 컨테이너 밖에서 실행할 수 없고 테스트가 어렵고 코드의 유지보수가 힘듭니다.
    초기 컴포넌트에 접근시 DL을 사용해야 하는 경우가 많습니다.
  2. DI(Dependency Injection) : 의존성 주입
    컨테이너가 Bean 설정 정보를 바탕으로 의존관계를 자동으로 연결해 주는 방식입니다. IoC 구현시 기본적으로 DI방식으로 구현하되 그렇지 못한경우 DL방법을 이용합니다.
    DI에는 Setter Injection, Constructor Injection, Method Injection 세 가지 방법이 있습니다.

DI 구현 방법

  • Setter Injection : Setter 메서드를 이용하는 방법 인자가 없는 생성자나 메서드의 bean을 인스턴스화 하기 위해 사용합니다.
    • 객체 생성 후 의존성을 주입하는 방식이기 때문에 구현시에 유연하게 사용할 수 있습니다.
    • setter를 통해 값을 할당 받기 전까지는 객체를 사용할 수 없습니다.
public class ToyService {
    private ToyRepository toyRepository;

    public void setToyRopository(ToyRepository toyRepository) {
        this.toyRepository = toyRepository;
    }
}

  • Constructor Injection : 생성자를 이용하는 방법
    • 생성자에 파라미터를 지정함으로써 객체가 필요로 하는 것을 명확하게 알 수 있습니다.
    • 필드를 불변 값으로 만들 수 있습니다.
public class ToyService {
    private ToyRepository toyRepository;

    public ToyService(ToyRepository toyRepository) {
        this.toyRepository = toyRepository;
    }
}

  • Method Injection : Singleton 인스턴스와 Non Singleton 인스턴스의 의존관계를 연결 시킬 때 사용됩니다. 많이 사용하지 않습니다.
반응형

'Spring' 카테고리의 다른 글

[JPA] QueryDSL Q class 생성 안될때  (0) 2020.08.03
[Spring] Spring Framework뼈대  (0) 2020.07.17
[Spring] AOP 구현 - Annotation  (0) 2020.07.09
[Spring] ORM, JPA, Hibernate, Spring Data JPA의 개념  (0) 2020.07.08
[Spring] AOP 구현 (XML)  (0) 2020.07.06