오늘의하루

Spring 의존 관계 주입 정리 본문

Spring

Spring 의존 관계 주입 정리

오늘의하루_master 2023. 8. 21. 02:24

의존관계 주입

@Autowired는 기본적으로 등록된 빈의 타입으로 주입한다.

  • 스프링이 빈을 모두 등록한 후 의존관계를 주입해준다.
  • 기본적으로 주입할 대상이 빈에 등록되지 않으면 오류가 발생하며, 이를 막고 싶다면 @Autowired(required=false)로 지정하면 된다.

의존 관계 주입 4가지 방법

생성자 주입

생성자 호출 시점에서 딱 1번만 호출되는 것을 보장된다.

  • 불변, 필수 의존 관계에서 사용한다.
  • 생성자가 하나라면 @Autowried를 생략할 수 있다
    • 스프링이 빈을 등록할때 결국 인스턴스화 할때 new 연산자를 사용하기 때문이다.

수정자 주입(setter 주입)

선택, 변경 가능성이 있는 의존관계에서 사용한다.

필드 주입 (권장하지 않는다.)

코드가 간결하지만 순수 자바 테스트가 힘들다는 단점이 있다.

  • 테스트가 하고 싶다면 setter를 만들어야 한다.

DI 프레임워크가 없다면 아무것도 할 수 없다.

애플리케이션의 실제 코드와 관계없는 테스트 코드를 만들때는 사용가능하다.

일반 메서드 주입 (잘 사용하지 않는다.)

한번에 여러 필드를 주입 받을 수 있다.

 

@Autowired 옵션 처리

required=false : 주입할 대상이 없다면 메소드 자체가 호출되지 않는다.
@Nullable : 자동 주입할 대상이 없으면 null이 입력된다.
Optional<T> : 자동 주입할 대상이 없다면 Optional.empty가 입력된다.

 

생성자 주입을 사용해야 하는 이유!

1. 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료 시점까지 변경할 일이 없어야 한다.

2. 누군가 실수로 변경할 수 있거나 변경하면 안되는 메소드를 열어두는 것은 좋은 설계가 아니다.

3. 프레임워크 없이 순수 자바 코드를 단위 테스트할 수 도 있다.

4. final 키워드 가능하다.

 

생성자 주입을 사용하면 필드에 final 키워드를 사용해서 값이 설정되지 않는 오류를컴파일 시점에서 막아준다.

  • 컴파일 오류는 가장 빠르고 좋은 오류다.

요약정리

  1. 생성자 주입 방식은 프레임워크에 의존하지 않고 순수 자바의 특징을 잘 살릴 수 있는 방법이다.
  2. 기본으로 생성자 주입을 사용하고 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여하면 된다.
  3. 생성자 주입과 수정자 주입은 동시에 사용 가능하다.
  4. 필드 주입은 사용하지 않는게 좋다.

 

lombok을 이용한 생성자 주입 코드 줄이기

주입해야할 코드가 늘어나도 생성자를 수정할 필요가 없다.

@Component
@RequiredArgsConstructor // final이 붙은 필드들을 생성자로 만들어준다.
public class ServiceImpl implements Service{
	private final Repository repository;
	private final Policy policy;
	
	// 생략 가능 : 생성자가 하나이면 @Autowired가 생략가능하기 때문이다.
	// @Autowired
	// public ServiceImpl(Repository repository, Policy policy){
	// 	this.repository = repository;
	//	this.policy = policy;
	// }
}

 

의존 관계 주입시 타입이 같은 빈이 2개 이상일 경우 해결방법

쉽게 생각해보면 해결하는 방법은 우선 하위 타입(구체화)을 지정하면 가능하지만 이는 DIP를 위반하고 유연성이 떨어지고 이름만 다르고 똑같은 타입이 스프링 빈에 2개 있으면 해당 방법으로는 해결이 불가능하다.

해결방법

  1. @Autowried 필드명 매칭
    1. 타입으로 우선 매칭 시도하고 2개 이상일 경우 필드 이름, 파라미터 이름으로 빈이름을 추가 매칭한다.
  2. @Qualifier 끼리 매칭
    1. 이건 추가 구분자 역할을 하는 것이지 빈 이름을 변경하는 것이 아니다.
    2. 컴파일 과정에서 타입 체크가 안된다는 단점을 가지고 있다.
  3. @Primary 사용
    1. 사용할 구체화 클래스에 @Primary를 붙이면 우선 순위가 올라사서 주입시 해당 빈을 주입한다.

주의사항 : @Primary보다는 @Qualifier이 우선권을 갖는다.

'Spring' 카테고리의 다른 글

Spring Bean Scope  (0) 2023.08.21
Spring Bean 생명 주기 콜백  (0) 2023.08.21
Spring ComponentScan 관련 정리  (0) 2023.08.20
[Spring] 싱글 톤 관련 정리 및 주의사항  (0) 2023.08.20
BeanFactory와 ApplicationContext  (0) 2023.08.20
Comments