Search
Duplicate
🚀

Denpendancy Injection

의존성 주입이란?

프로그램 디자인이 결합도를 느슨하게 되도록하고 의존관계 역전 원칙을 따르도록 클라이언트의 생성에 대한 의존성을 클라이언트의 행위로부터 분리하는 것이다.

예시

여기서 객체 AB에 의존하고 있다. 즉 의존성이 존재한다. A를 사용하기 위해선 b가 생성된 후 주입되어 있어야 한다.
public class A { private B b; }
Java
복사
의존성 주입은 객체가 필요로 하는 다른 객체를 직접 생성하는 대신, 생성자 파라미터, 팩토리 메소드 인수 또는 속성으로 정의하고 컨테이너가 객체를 생성할 때 해당 의존성을 주입하는 프로세스다.
이처럼 의존 관계를 외부에서 결정하고 주입하는 것을 관리하고 사용하게 만드는 것을 의존성 주입이라고 한다.
이를 통해 객체 간의 의존 관계를 느슨하게 유지하여 유지보수에 도움이 되도록하는 것이다.

의존성 주입의 장점

결합도가 감소한다.
의존성 주입을 사용하면 객체의 의존성을 외부에서 관리해주므로 결합도가 낮아지고 이로인해 유지 보수성이 향상된다.
테스트가 용이해진다.
특정 객체를 검증할 때, 해당 객체가 의존성을 가진 다른 객체를 테스트 더블로 대체하여 처리할 수 있다.

의존성 주입의 종류

필드 주입

@Component public class A { @Autowired private B b; }
Java
복사
개요
필드에 @Autowired 어노테이션을 추가하여 의존성을 주입하는 방법이다.
즉, 객체의 필드를 사용하여 의존성을 주입하는 방식이다.
특징
외부에서 접근이 불가능하다.
DI 컨테이너 상에서만 동작하므로 순수 자바 코드로 테스트하기 어렵다.
필드를 수정할 수 없게 되므로 테스트를 위해 의존성을 모킹하기 어렵기 때문이다.
통합 테스트라면 괜찮지 않을까? 비관리 의존성에는 사용하지 않는식으로..
어플리케이션의 실제 코드와 상관없는 특정 테스트를 하고 싶을때 사용하는 것이 좋다.

Setter, Method 주입

@Component class A { private B b; @Autowired public void setB(B b) { this.b = b; } }
Java
복사
POJO
class A { private B b; public void setB(B b) { this.b = b; } }
Java
복사
개요
setter 메소드에 @Autowired 어노테이션을 붙여 의존성을 주입할 수 있다.
@Component를 통해 실행되는 클래스를 빈으로 등록하고 의존관게를 주입하게 된다.
@Autowired가 있는 setter 메소드들은 자동으로 의존관계를 주입한다.
특징
의존 관계가 변경될 수 있다. 또한 초기 값이 없으므로 NPE가 발생할 가능성이 있다.
가급적이면 변경 가능성이 있는 의존 관계에 사용하는 것이 좋다.

생성자 주입

@Component public class A { private final B b; @Autowired public A(B b) { this.b = b; } }
Java
복사
POJO
public class A { private final B b; public A(B b) { this.b = b; } }
Java
복사
개요
생성자 주입은 컨테이너가 생성자를 호출하면서 이뤄지는 의존성 주입이다.
이는 정적 팩토리 메소드를 호출하여 빈을 생성하는 것과 비슷한 원리로, 스프링 공식문서에서도 이를 유사한 경우라고 언급하고 있다.
spirng.io 개발팀이 일반적으로 최선의 경우라고 추천한다.
생성자에 @Autowired 어노테이션을 붙여 의존성을 주입할 수 있다.
특징
객체 생성 시점에 모든 의존성이 주입되므로 객체의 불변성을 보장하므로 객체가 안정적이다.
final 키워드를 사용할 수 있으므로 컴파일 시 의존성 문제를 발견할 수 있다.
의존하는 객체가 존재하지 않을 때, 컴파일 시점에 오류가 발생하므로 런타임 오류를 예방할 수 있다.