본문 바로가기

📑WIL & TIL

Week3 WIL : DI, IoC, Bean

 DI (Dependency Injection) 란? 

  • 의존성 주입이라고 한다.
  • 객체의 의존성을 개발자가 아닌 외부(IoC Container)에서 주입함으로써 객체 간의 결합을 약하게 해주며 유지보수가 쉬운 코드로 만들어준다.
  • 스프링에서는 스프링 컨테이너Bean 설정 정보를 바탕으로 각 클래스의 의존관계를 자동으로 결정 및 연결해준다.

 

 1) 의존성이란? 

한 객체가 다른 객체를 사용할 때 의존성이 있다고 한다.

예를 들어 Store 객체가 Pencil 객체를 사용하고 있는 경우에 우리는 Store객체가 Pencil 객체에 의존성이 있다고 표현한다.

public class Store {

    private Pencil pencil;

}

 

 2) 의존성 주입은 왜 필요한가? 

연필이라는 상품과 1개의 연필을 판매하는 Store 클래스가 있다고 하자.

public class Store {

    private Pencil pencil;

    public Store() {
        this.pencil = new Pencil();
    }
    
}

 

위 클래스의 문제점은

① 두 클래스가 강하게 결합되어 있음

만약 Store 에서 Pencil 이 아닌 Food 와 같은 다른 상품을 판매하고자 한다Store 클래스의 생성자 변경이 필요하다.

각각 다른 상품들을 판매하기 위해 생성자만 다르고 나머지는 중복되는 Store 클래스들이 파생된다면 유연성이 떨어진다.

 

② 객체들 간의 관계가 아니라 클래스 간의 관계가 맺어짐

올바른 객체 지향적 설계라면 객체들 간의 관계가 맺어져야 한다.

다른 객체의 구체 클래스 (Pencil 인지 Food 인지 등) 를 전혀 알지 못하더라도,

(해당 클래스가 인터페이스를 구현했다면) 인터페이스의 타입(Product)으로 사용할 수 있다.

👉아래 예시코드로 자세히 설명

 

 3) 의존성 주입을 통한 문제 해결 

Pencil, Food 등 여러가지 제품을 하나로 표현하기 위해서는 Product 라는 Interface 가 필요하다.

public interface Product {

}

 

public class Pencil implements Product {

}

 

 

이제는 Store 와 Pencil 이 강하게 결합되어 있는 부분을 제거하고, 외부에서 상품을 주입(Injection) 받아야 한다.

(그래야 Store에서 구체 클래스에 의존하지 않게 됨)

public class Store {

    private Product product;

    public Store(Product product) {
        this.product = product;
    }

}

 

 

우선  DI 컨테이너가 필요한데 그 이유는 Store 에서 Product 객체를 주입하기 위해서는 Application 실행 시점에 필요한 객체(bean)를 생성해야 하며, 의존성이 있는 두 객체를 연결하기 위해 한 객체를 다른 객체로 주입시켜야 하기 때문이다.

즉, Pencil 이라는 객체를 만들고 그 객체를 Store 로 주입시켜주는 역할을 DI 컨테이너가 한다.

public class BeanFactory {

    public void store() {
        // Bean의 생성
        Product pencil = new Pencil();
    
        // 의존성 주입
        Store store = new Store(pencil);
    }
    
}

 

이러한 개념은 제어의 역전(Inversion of Control, IoC)라고 불리기도 한다.

어떠한 객체를 사용할지에 대한 책임은 프레임워크에게 넘어갔고, 자신은 수동적으로 주입받는 객체를 사용하기 때문이다.

IoC 에 대한 설명은 아래에서 자세히 설명하겠다.

 

마지막으로 DI를 정리하자면 

의존성 주입을 도와주는 DI 컨테이너로 강하게 결합된 클래스들을 분리하고, 애플리케이션 실행 시점에 객체 간의 관계를 결정해 줌으로써 결합도를 낮추고 유연성을 확보해준다.

 

 4) 의존성 주입의 장점 

  • 두 객체 간의 관계라는 관심사의 분리
  • 두 객체 간의 결합도를 낮춤
  • 객체의 유연성을 높임
  • 테스트 작성을 용이하게 함

 

 IoC (Inversion Of Control) 란? 

제어의 역전이라 부르고, 프로그램의 흐름 (객체의 생성, 생명주기) 을 개발자가 직접 제어하는 것이 아닌

외부(Ioc Container)에서 제어 및 관리해주는 것으로, 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.

 

👉흔히 스프링 프레임워크를 이용해서 개발할 때 여러가지 Bean을 사용 할 것이다. 사용자의 요청이 들어오면 요청에 알맞은 Bean을 생성해서 필요한 일을 하도록 시킨다. 해당 Bean이 할 일을 마치면 Bean을 삭제해준다. 하지만 이런 객체의 생성과 소멸이 어떻게 이루어지는지 알 필요가 없다. 프로그래머가 직접 제어 할 필요가 없이 프레임워크가 직접 제어해주기 때문이다. 이것이 IoC 제어의 역전이다.

 

 IoC Container 란? 

  • Spring IoC Container가 객체를 관리함으로써 DI(의존성 주입) 가 가능해지게 된다.
  • Spring IoC Container가 주도권을 가져감으로써 객체의 관리, 의존관계의 결정 및 설정 등의 역할을 맡게된다.
  • 프로그래머가 작성한 코드를 스스로 참조한 뒤 알아서 객체의 생성과 소멸(객체의 생애 주기)을 관리한다.

 

 Bean 이란? 

스프링에서 빈(Bean)이란 "자바 객체"를 말한다.

 

 Bean 과 자바 객체의 차이점? 

Bean스프링 Ioc 컨테이너가 관리하는 자바 객체다.
자바 객체스프링 Ioc 컨테이너가 관리하지 않는 객체도 포함된다.

 

 

<출처 및 참고내용>

https://mangkyu.tistory.com/150

 

[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유

1. 의존성 주입(Dependency Injection)의 개념과 필요성 [ 의존성 주입(Dependency Injection) 이란? ] Spring 프레임워크는 3가지 핵심 프로그래밍 모델을 지원하고 있는데, 그 중 하나가 의존성 주입(Dependency Inj

mangkyu.tistory.com

 

https://velog.io/@dplo1514/Spring-IOC%EC%A0%9C%EC%96%B4%EC%9D%98-%EC%97%AD%EC%A0%84-DI-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85

 

Spring IOC(제어의 역전) / DI (의존성 주입)

프로그램의 흐름 (객체의 생성 , 생명주기)을 개발자가 직접 제어하는 것이 아닌 외부에서 제어 및 관리해주는 것을 말한다.스프링에서는 Application을 구성하는 Bean을 관리하기 위하여 IOC개념을

velog.io

 

https://velog.io/@jkijki12/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-Bean-IoC-Container-DI%EA%B0%80-%EB%AD%94%EB%8D%B0

 

[Spring] 스프링 Bean, IoC Container, DI가 뭔데!!

Spring Core인 Bean, IoC, Container를 알아보자!

velog.io

 


주특기 입문 주차에 들어섰는데 강의를 봐도 무슨 말인지 모르겠고 낯선 용어들로만 설명을 들으니 이해하기 너무 힘든 한 주였다.

코드를 반복해서 사용하고 눈에 익숙해지다보니 대충은 알 것 같지만 직접 말로 설명해보라고 하면 아무말도 나오지가 않는다. WIL 을 쓰면서 어느 정도 개념은 잡히는가 싶다가도 헷갈리는 것들 투성이다.

인내심을 가지고 코드 하나하나 분석해야 하나..? 싶다. 그래도 포기는 말자~