개발자로 후회없는 삶 살기

[문법] 의존관계 자동 주입 본문

[백엔드]/[spring | 학습기록]

[문법] 의존관계 자동 주입

몽이장쥰 2024. 7. 31. 16:25

서론

※ 과거에 기록한 내용에서 중요한 부분만 발췌하여 모두가 이해하기 쉽게 다시 서술한다.

 

본론

- 다양한 의존 관계 주입 방법

1. 생성자 주입

빈에 등록하기 위해 생성자를 호출할 때, @Autowired가 있으면 생성자의 인자의 타입에 해당하는 스프링 빈을 컨테이너에서 찾아서 주입한다.

 

1) 생성자 호출 시점에 딱 1번만 호출되고 변하지 않은 불변 의존관계를 보장하고자 할 때 사용
2) 생성자가 하나면 autowired 생략 가능
3) 빈 등록과 의존 관계가 동시에 일어남

 

2. 세터 주입

set 메서드에 autowired를 붙이면 된다. 재대입으로 인해, final을 제거해야 한다. 빈을 등록하는 단계와 의존 관계를 주입하는 단계가 나뉘어져 있고 빈을 전체 한 번에 다 생성하고 주입을 하는 순서이다.

 

3. 필드 주입

필드에 넣어버리는 주입 방법으로, 간결하지만 외부에서 변경이 불가능해서 테스트하기 힘들다는 단점이 있다. 수정이 불가하여 수정하려면 세터를 열어야 한다. 컨테이너 방식에서 사용하지 않는다.

 

- 옵션 처리

autowired만 사용하면 required 옵션의 기본값이 true라서 자동 주입 대상이 컨테이너에 없으면 오류가 발생한다. 자동 주입 대상을 옵션으로 처리하는 방법은 다음과 같다.

 

1. required 파라미터 false

컨테이너에 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출이 안 된다. 현재 Member 클래스가 스프링 관리 대상 빈이 아닌 상황이다.

 

true로 하면 Member가 빈이 아니라는 예외가 발생한다. false는 set 자체를 실행하지 않아서 자동 주입을 아예 안 한다.

 

2. @Nullable

자동 주입할 대상이 없어도 호출은 되지만 null이 대신 들어간다.

 

생성자 주입을 선택해라

생성자 주입을 사용하면 좋은 점을 말해보자

 

1. 불변

대부분의 주입은 배역이 정해지면 앱이 종료할 때까지 의존관계 주입을 변경할 일이 없다. 목적 자체가 바꾸지 않으려고 하면 생성자 주입이 최고이다.

 

2. 누락

주문 서비스는 레포지토리와 할인 정책이 필요하다. 이때 인자로 넣지 않고 실행하는 상황이다.

 

수정자 주입을 쓰면 누락할 수 있고 null에 참조를 해서 NPE를 발생시킨다.

 

반면, 생성자 주입을 쓰면 컴파일 오류가 일어나서 누락을 막을 수 있다.

 

3. final 키워드를 넣을 수 있음

final을 안 붙이면 생성자에 대입을 안 해도 에러가 발생하지 않는다. 이를 막을 수 있는 방법이 final을 넣는 것으로 final을 넣으면 초기화가 필수라서 컴파일러가 알려준다.

 

- 조회 빈이 2개 이상인 문제

autowired는 타입으로 빈을 가져온데 같은 타입 빈이 2개 이상 등록된 상황이다.

 

1. Autowired의 필드명 매칭

autowired는 처음엔 타입으로 가져오고, 동일 타입이 여러 개면 생성자 파라미터 명으로 추가로 가져온다. 파라미터 명을 rate로 바꾸면 같은 타입의 스프링 빈 중에 이름에 매칭되는 빈 객체를 가져온다.

 

2. Qualifier 매칭

추가 구분자를 붙여주는 방법으로 실제 빈 이름을 변경하는 것은 아니다. 사용하려면, 생성자 주입하는 파라미터 명은 그대로 두고 qualifier를 붙인다.

 

3. primary

자주 사용하는 방법으로, 여러 빈이 매칭되어도 무조건 primary가 붙은 애가 주입된다.

 

-> primary와 qualifier 사용하는 경우

메인 DB와 보조 DB가 있는 상황에서 보조 DB는 어쩌다 한 번 가져온다면, 모든 구현체에 qualifier를 붙이면 매번 qualifier를 써야하고, 또 메인에만 primary를 적으면 가끔 보조를 쓸 때 불편한다. 따라서 메인에 primary를 걸어서 대부분 메인 DB가 불려지게 하고 보조 DB를 사용할 때를 대비하여 보조 DB에 qualifier를 붙여놓고 필요시에만 사용할 수 있다.

 

4. 어노테이션 직접 만들기

@Component에 있는 어노테이션들과 qualifier를 붙이고 등록하는 쪽에 붙이고

 

주입 받는 곳에도 붙이면 된다.

Comments