2023. 4. 14. 20:09ㆍ공부/Spring
스프링에서 제공하는 의존성 주입에 대해 톺아보자.
먼저 의존성이란 무엇인지 간단하게 설명하면 다음과 같다.
A라는 객체가 B라는 객체를 의존할때, 의존 대상인 B가 변하면 A도 그 영향을 받는다.
햄버거를 예로 들면
다음과 같은 HamburgerRecipe이라는 클래스가 존재하고 해당 클래스는 Bun, Patty, Vegetable이라는 클래스를 의존한다.
이때, 의존대상인 Bun, Patty, Vegetable 클래스들이 변하면 HamburgerRecipe도 그 영향을 받는다. 만약 Patty 클래스에서 다음과 같은 변경이 발생했다면,
위와 같이 HamburgerRecipe 클래스도 그 영향을 받는것을 확인 할 수 있다. 실제로는 훨씬 복잡한 개발환경속에서 이러한 의존성 문제가 계속 발생하면 매우 귀찮을 것이다. Spring에서는 의존성 주입이라는 기능을 제공한다. 스프링의 핵심 기능중 하나인 의존성 주입에 대해 알아볼건데 이를 위해선 IoC를 빼놓을 순 없다. 이것도 함께 알아보자.
먼저 의존성 주입에는 3가지 방식이있다.
- 생성자 주입
- Setter 주입
- Method 주입
1. 생성자 주입 방식 (Construction Injection)
생성자를 통해 객체를 전달받는 방식이며, Spring 에서 권장하는 DI 주입 방식이다. 권장하는 이유는
필수적으로 사용해야 하는 의존 대상 없이는 Instance를 만들지 못하도록 강제할 수 있기 때문이다. (안정성)
생성자 코드에서 보면 알수 있듯, private final로 선언되어 생성자를 주입받아 클래스 안에서 사용하게 된다. 이 말은 초기화는 딱 한번만 가능하며 한번 선언되면 변하지 않는 메서드가 되는데 나중에 변경될 위험을 방지 할 수 있다. 또한 final이 붙어 초기화가 되지 않으면 무조건 Null Pointer Exception을 방지 할 수 있다.
package org.burger;
public class ConstructorInjection_BurgerRecipe {
private final Bun bun;
private final Patty patty;
private final Vegetable vegetable;
//생성자 주입방식
public ConstructorInjection_BurgerRecipe(Bun bun, Patty patty, Vegetable vegetable) {
this.bun = bun;
this.patty = patty;
this.vegetable = vegetable;
}
}
2. Setter 주입 방식 (Setter Injection)
객체 생성 후에 Setter 메서드를 통해 의존성을 주입하는 방식인데, Setter 매서드를 호출하지 않으면 해당 의존성이 null 값으로 유지될 수 있으므로, NullPointerException 등의 오류가 발생할 수 있다. Setter 매서드를 통해 의존성을 주입받기 때문에 선택적인 의존성을 주입할 수 있다.
package org.burger;
public class SetterInjection_BurgerRecipe {
private Bun bun;
private Patty patty;
private Vegetable vegetable;
public void setHamburgerRecipe(Bun bun, Patty patty, Vegetable vegetable){
this.bun = bun;
this.patty = patty;
this.vegetable = vegetable;
}
}
3. 매서드 주입방식 (Method Injection)
필드를 집적 가지고 있는 것이 아니라 메소드를 통해 인자로 넘겨받는 방식으로 주입받음
package org.burger;
public class MethodInjection_BurgerRecipe {
public void cook(Bun bun, Patty patty, Vegetable vegetable){
bun.Slice();
patty.Grill();
vegetable.Chopping();
}
}
4. 필드주입
# 의존성 주입의 장점
이러한 의존성 주입을 하는 이유가 무엇인지 궁금하다. 어떻게 쓰는지는 알겠는데, 왜 쓰는가?
- 클래스간의 결합도가 낮아짐
- => 코드 재사용률이 높아짐
- => 단위 테스트의 편의성이 높아짐
- => 코드의 가독성이 좋아짐
- => 시간과 비용 절약
'공부 > Spring' 카테고리의 다른 글
[Spring] 의존성 역전 원칙 (Dependency Inversion Principle, DIP) (0) | 2023.04.15 |
---|---|
[Spring] Dependency Injection & IoC 톺아보기(2) - 강한결합 & 약한결합 (0) | 2023.04.15 |
[Lombok] @Builder.default (0) | 2023.02.08 |
[Querydsl] fetchResult() 가 deprecated 된 이유 (1) | 2023.02.02 |
@RequestBody에 왜 기본생성자는 필요하고 Setter는 필요 없을까? (1) | 2023.01.29 |