[SpringBoot] Di에 대해서

손채윤·2024년 1월 29일

1.Di(의존성 주입, Dependency Injection)이란?

-외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴.

-인터페이스를 사이에 둬서 클래스 레벨에서는 의존관계가 고정되지 않도록 하고 런타임 시에 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮출 수 있게 함.

-쉽게 말하자면, 두 객체 간의 관계(의존성)를 맺어주는 것.

-생성자 주입, 필드 주입, 수정자 주입

[의존성이란?]

한 객체가 다른 객체를 사용할 때 의존성이 있다고 한다.
ex)store객체가 pencil객체를 사용하고 있는 경우에 store객체가 pencil객체에 의존성이 있다고 표현한다.

Public class Store{

	private Pencil pencil;
}




2.의존성 주입이 필요한 이유

public class Store {

    private Pencil pencil;

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

위의 클래스는 두 클래스가 강하게 결합되어 있고, 객체들 간의 관계가 아니라 클래스 간의 관계가 맺어졌다는 문제점이 있다.

1.두 클래스가 강하게 결합되어 있음
Store에서 Pencil이 아닌 Food를 사용한다면 Store클래스의 생성자에 변경이 필요하다. 즉, 유연성이 떨어진다. 각각의 다른 상품들을 판매하기 위해 생성자만 다르고 나머지는 중복되는 Store클래스들이 파생되는 것은 좋지 못하다.

2.객체들 간의 관계가 아니라 클래스 간의 관계가 맺어짐
위의 클래스는 객체들 간의 관계가 아니라 클래스들 간의 관계가 맺어져 있다. 올바른 객체지향적 설계라면 객체들 간에 관계가 맺어져야 한다.



3.의존성 주입

Pencil,Food등 여러가지 제품을 하나로 표현하기 위해서는 Product라는 인터페이스가 필요하다. 그리고 pencil에서 Product 인터페이스를 구현하자.

public interface Product {

}

public class Pencil implements Product {

}

이제 Store와 Pencil이 강하게 결합되어 있는 부분을 제거해야 한다. 이를 제거하기 위해서는 다음과 같이 외부에서 상품을 주입받아야 한다. 그래야 Store에서 구체 클래스에 의존하지 않게 된다.

public class Store {

    private Product product;

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

}

이러한 이유로 우리는 Spring이라는 Di 컨테이너를 필요로 하는 것이다. Store에서 product 객체를 주입하기 위해서는 애플리케이션 실행 시점에 필요한 객체(빈)를 생성해야 하며, 의존성이 있는 두 객체를 연결하기 위해 한 객체를 다른 객체로 주입시켜야 한다.

예를 들어 다음과 같이 pencil이라는 객체를 만들고, 그 객체를 Store로 주입시켜주는 역할을 위해 Di컨테이너가 필요하다.

public class BeanFactory {

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

이러한 부분은 스프링 프레임워크가 완벽하게 지원을 해준다. 스프링은 특정 위치부터 클래스를 탐색하고, 객체를 만들며 객체들의 관계까지 설정해준다. 이러한 이유로 스프링은 Di컨테이너라고도 불린다.

0개의 댓글