의존 관계 Dependency
스프링은 의존관계 주입 컨테이너, DI컨테이너라고도 불린다. 여기서 말하는 의존관계 즉, 의존성은 한 객체가 다른 객체에 의존하고 있다는 의미를 가지고 있다. 객체 지향 프로그래밍에서는 다른 객체를 사용하기 위해 호출을 할 때, 파라미터를 이용해 메세지를 주고 받거나, 객체를 직접 가져오기도 한다. 이 모두 의존관계가 형성되어 있는 것이다.
의존성은 컴파일 의존성과 런타임 의존성으로 나뉘게 된다.
컴파일 의존성 Compile Dependency (정적 의존성, Static Dependency)
컴파일은 소스코드가 기계어로 변환하는 시점으로, 컴파일타임 의존성은 컴파일러가 직접 관리하여 코드를 통해 의존성을 확인한다. 코드 자체에서 어떤 객체를 참고할지 결정하고 있기 때문에 정적 의존성이라고 불린다.
이 경우 A가 B의 메소드를 호출하며 사용한다고 했을 때, 만약 B에서 메소드가 변경되거나 삭제되는 등 업데이트가 생기면 A에서 수행을 할 때도 영향을 주게 된다.
런타임 의존성 Runtime Dependency (동적 의존성, Dynamic Dependency)
런타임 의존성은 코드 실행 중에 의존성이 결정되는 방식으로, 추상클래스나 인터페이스를 사용하여 컴파일러가 의존관계를 파악하기 힘들다. 스프링에서 의존 객체를 주입받을 때 사용하는 방식은 이 런타임 의존성이다. XML파일이나 어노테이션을 이용해 의존성을 쉽게 변경할 수 있다.
인터페이스를 사용한다는 건 SOLID원칙 중 DIP원칙과 관련되어 있기도 하다. 인터페이스에 의존관계를 만들어두면 인터페이스 구현 클래스와는 관계가 느슨해져 변화에 영향을 덜 받는 낮은 결합도를 이루게 된다.
💫 의존 역전 원칙: 직접 참조하지 말고, 추상클래스나 인터페이스 등 상위 요소로 참조하라.
이 런타임 의존관계 방식은 런타임 시에 오브젝트 사이에서 만들어지는 의존관계하는 오브젝트 의존관계라고 불리기도 한다. 여기서 실제 사용대상인 오브젝트를 의존 오브젝트, 의존 객체라고 한다.
의존 관계 주입 Dependency Injection (DI)
의존 오브젝트에 사용할 주체와 클라이언트를 더하여 의존성 주입을 할 수 있다. 런타임 의존성 방식을 사용하며 아래와 같은 특징을 가지고 있다.
- 런타임 시 모델이나 코드 자체에서 의존관계가 드러나지 않고, 인터페이스에만 의존하고 있어야 한다.
- 런타임 의존관계는 컨테이너나 팩토리같은 제3의 존재가 결정한다.
- 의존 오브젝트에 대한 레퍼런스를 외부에서 제공하여 만들어진다.
스프링의 애플리케이션 컨텍스트, 빈 팩토리, IoC컨테이너 등은 외부에서 런타임 관계를 맺어주는 제 3의 존재로 볼 수 있다. 이와 같이 의존성을 주입하여 사용하는 방법은 컴파일 의존성에 비해 결합도를 낮추고, 유연성과 가독성을 상승시킨다.
의존 관계 주입 방법
생성자 주입 방법 Constructor-based Dependency Injection
- 생성자를 이용해 의존성을 주입하는 방법. 주입 받은 객체가 변하지 않거나, 반드시 객체 주입이 필요한 경우 사용.
수정자 주입 방법 Setter-based Dependency Injection
- Setter 메서드를 이용해 주입하는 방법. 주입받는 객체가 변경될 가능성이 있을 경우 사용.
DI 컨테이너
의존관계 주입 작업을 주도하는 컨테이너를 DI컨테이너라고 한다. DI는 자신이 사용할 오브젝트에 대한 선택과 생성 제어권을 외부로 보내며, 자신은 수동적으로 주입받은 오브젝트를 사용한다. IoC개념을 가지고 있어 IoC/DI 컨테이너라는 이름으로 사용하기도 한다.
의존 관계 검색 Dependency Lookup (DL)
의존성을 맺을 때 스스로 검색하는 방법을 의존관계 검색 DL이라고 한다. 어떤 오브젝트를 이요할지 결정하지 않지만, 의존 오브젝트를 능동적으로 찾는 방식이다. 미리 정해둔 이름을 전달해 그 이름에 해당하는 오브젝트를 검색한다. getBean()
을 이용해 동작하는 것은 이 DL방식과 같다.
DI와 DL비교
- DL
- 코드 안에 팩토리나 API가 나타남 → 다른 오브젝트에 의존
- 의존 관계 주입이 더 깔끔하게 작성 됨
- 검색하는 오브젝트는 스프링의 bean일 필요가 없음
- DI
- A와 B 사이 DI가 적용되기 위해 둘 다 bean이어야 함
- IoC방식으로 컨테이너에서 생성되는 오브젝트는 Bean
reference
"토비의 스프링3.1 Vol.1 스프링의 이해와 원리", 1.7 의존관계 주입(DI)
"[Spring] 의존관계 주입(Dependency Injection), 의존성 주입, DI란?", 코드연구소, https://code-lab1.tistory.com/122
"컴파일 타임 의존성과 런타임 의존성", 코딩공장장, https://developer111.tistory.com/
'Framework > Spring' 카테고리의 다른 글
[Spring] Enum에 i18n 적용하는 방법 (0) | 2025.02.12 |
---|---|
[Spring] Global Exception Handler에서 Enum 사용하기 (0) | 2025.02.12 |
[Spring] 싱글톤 레지스트리(Singleton Registry)란? (0) | 2024.12.09 |
[토비의스프링] 1.5 스프링의 IoC (0) | 2024.12.03 |
[토비의스프링] 1.4 제어의 역전(IoC) (1) | 2024.11.29 |