Spring DI -1-

Dobi·2024년 3월 31일

Spring

목록 보기
2/6

Spring DI (의존성 주입, Dependency Injection) ?

스프링 프레임워크는 3가지 핵심 프로그래밍 모델을 지원하는데, 그 중 하나가 의존성 주입 DI(Dependency Injection) 이다.

"의존성"은 예를 들어 서비스로 사용할 수 있는 객체이다. 클라이언트가 어떤 서비스를 사용할 것인지 지정하는 대신, 클라이언트에게 무슨 서비스를 사용할 것인지를 말해주는 것이다.
"주입"은 의존성(서비스)을 사용하려는 객체(클라이언트)로 전달하는 것을 의미한다.
의존성 주입은 프로그램 디자인이 결합도를 느슨하게 되도록하고 의존관계 역전 원칙과 단일 책임 원칙을 따르도록 클라이언트의 생성에 대한 의존성을 클라이언트의 행위로부터 분리하는 것이다
출처: 위키백과


다음과 같은 예에서 WaterBottle 객체가 Water객체에 의존성이 있다고 말한다.

public class WaterBottle{

	private Water water;
    
}

두 객체간 의존성 관계를 맺는 것을 의존성 주입이라고 한다. 의존성 주입 방식에는 생성자 주입, 필드 주입, 메서드 주입(수정자) 등 여러 방법이 있지만 앞의 세가지가 제일 대표적인 방법이다.

DI의 필요성

위의 예를 다시보자.

public class WaterBottle{
	
    private Water water;
    
    public Waterbottle(){
    	this.water = new Water();
    }
}

이 상황에서 생성자를 통해 Water 객체를 생성해서 할당했다.
이 경우, WaterBottle 클래스와 Water 클래스는 강하게 결합되어있고 이를 '결합도가 높다'라고 표현한다. 또한 객체들 간의 관계가 아닌 클래스들 간의 관계가 생겨버렸다.

1) 두 클래스의 결합도가 높은 상황

결합도가 높은 것을 문제가 있다고 표현하는데 왜일까?
예를 들어, 현재 병에 물이 들어있는데 물을 주스로 변경한다고 생각해보자. Water를 Juice 로 변경하려면 WaterBottle() 생성자 자체를 변경해야하는 문제가 발생된다. 확장성에 대한 유연성이 떨어지는 상황인 것이다.

2) 클래스 간의 관계

클래스간의 관계가 생긴 것이 왜 문제일까?
객체 지향적 설계라는 말에서 알 수 있다. 객체 지향적 설계에서는 말그대로 객체들간의 관계를 생성해야하는데 위의 상황에서는 클래스간의 관계가 형성되었다. 올바른 객체 지향적 설계라면 Water, Juice 등의 클래스를 모르더라도 인터페이스 타입으로 사용할 수 있다.


위와 같은 문제를 WaterBottle에 어떤 음료를 넣을지에 대한 관심사가 분리되지 않았다 라고 표현하고 스프링에서는 이를 DI를 통해 해결하려고 했다.

의존성 주입(Dependency Injection)

먼저, 의존성 주입을 위해서는 다형성을 형성해야한다.

public interface Drink{

}

public class Water implements Drink{

}

또한 위의 예에서 WaterBottle 클래스에서 생성자로 강하게 결합 되어있는 문제를 제거해야 한다.

public class Bottle{
	
    private Drink drink;
    
    public Bottle(Drink drink){
    	this.drink = drink;
    }

}

위의 예에서 이제 Bottle은 Drink객체만 알지 어떤 음료인지는 알지 못한다. 스프링에서는 Bottle에 Drink 객체를 주입하기 위해 DI 컨테이너가 필요하다.

또한, 애플리케이션 실행 시점에 빈(객체)를 생성하고, 의존성이 있는 두 객체를 연결하기 위해 한 객체를 주입한다.

public class BeanFactory{
	public void botte(){
    	//Bean 생성
        Drink drink = new Water();
        
        //의존성 주입
        Bottle bottle = new Botte(drink);
    }
}

스프링 프레임워크가 완벽하게 DI를 지원해준다.
이런 일련의 개념을 스프링에서는 제어의 역전 (Inversion of Control, IoC) 라고 부른다. 어떤 객체를 사용할지에 대한 책임(제어)는 프레임 워크가 담당하고, 자신은 수동적으로 주입받은 객체를 사용하기 때문이다.

주의할 점은 DI == 스프링 IoC 라고 생각할 수 있고 맞다고 생각할 수 있는데 엄연하게 다르다. IoC가 DI를 활용해서 구현한 것이다.



출처
[Spring] 의존성 주입(Dependency Injection, DI)이란?
백기선 스프링 웹 MVC

profile
양말 받을 때까지 공부하는 개발자 도비

0개의 댓글