[Spring] 07-1. 의존관계 자동 주입

지찬우·2023년 1월 11일
0

Spring

목록 보기
21/27
post-thumbnail

이 시리즈는 인프런 강의(김영한 님의 ‘스프링 핵심 원리 - 기본편’)로 공부하며 혼자 기록하고, 사람들과도 공유할 수 있도록 작성하는 글이다. 최대한 추가적인 정보는 공식 홈페이지, 문서를 보며 얻을 예정이다.
(개인적인 생각과 이해가 들어가 있기 때문에 저의 ‘무식함’이 있을 수 있습니다😜 혹시라도 이 글을 보게 되시는 분이 계시다면 잘못된 부분 댓글로 많이 알려주시면 너무 감사하겠습니다!!)

GitHub Repository : https://github.com/jcw1031/spring-core-study


앞에서 컴포넌트 스캔을 공부하며 @Autowired를 사용한 의존관계 자동 주입을 간단히 살펴봤었다. 이번 시간에는 의존관계 자동 주입에 대해 자세히 살펴보자.

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

의존관계를 주입하는 방법은 크게 네 가지가 있다.

  • 생성자 주입
  • 수정자 주입(setter)
  • 필드 주입
  • 일반 메서드 주입

생성자 주입이 우리가 사용했던 방식이다. 각 방법의 특징을 알아보고 직접 코드로 작성해 보자.

1️⃣ 생성자 주입

생성자를 통해 의존관계를 주입받는 방법

특징

생성자 호출 시점에 딱 한 번만 호출되는 것이 보장된다. 따라서 불변(중간에 변경되지 않는다.)이어야 하거나 필수적(관례상 생성자의 매개변수에 값을 넣어야 한다 - null 제외)인 의존관계에 사용한다.

코드

생성자 주입은 우리가 그동안 사용했던 방식이다. 생성자 위에 @Autowired 어노테이션을 입력하여, 생성자로 의존관계를 주입받는다.

생성자가 단 하나만 존재하면 @Autowired를 생략해도, 스프링 빈에 한하여 자동 주입이 된다.

스프링 컨테이너의 라이프 사이클은 크게 두 가지로 나누어진다. 먼저 스프링 빈이 등록되고, 그 후에 의존관계가 주입된다. 하지만 생성자 주입은 빈을 등록할 때 생성자가 호출되기 때문에 의존관계도 한 번에 주입된다.

2️⃣ 수정자 주입

setter라 불리는 필드 값을 변경하는 수정자 메서드를 통해 의존관계를 주입받는 방법

특징

선택적이거나 변경 가능성이 있는 의존관계에 사용한다. 변경 가능성이란 흔하지는 않지만 실행 중간에 다른 인스턴스로 변경할 가능성이 있는 것을 뜻한다. 선택적인 경우는 **@Autowired(required = false)로 옵션 처리하여 필수가 아니도록 설정하면, 주입할 대상이 없어도 동작**하도록 할 수 있다.

수정자 주입만 옵션 처리가 가능한 것은 아니다. 옵션 처리는 뒤에서 알아볼 내용이다.

코드

아래처럼 set + 필드명으로 수정자 메서드를 만든다. 각 수정자 메서드 위에 @Autowired를 지정해 주면 수정자 의존관계 주입이 동작한다. 생성자가 필요 없고, 생성자를 작성하지 않으면 필드를 **private final이 아닌 private으로 선언**해야 한다. (또한 변경 가능성이 있는 의존관계에 사용하니 final이면 안 된다.)


3️⃣ 필드 주입

필드에 바로 주입하는 방법

특징

코드가 간결하기 때문에 예전에는 자주 사용하고 개발자들이 좋아할 수 있지만, 외부에서 변경이 불가능하기 때문에 테스트하기 어렵다. 여기서 테스트는 스프링을 사용하지 않고 순수 자바로 작성한 테스트를 의미한다. DI 프레임워크가 없으면 아무것도 할 수 없는 것이다. 따라서 사용하지 않는 것이 권장된다.

사용해도 괜찮은 경우도 있다. @SpringBootTest가 붙은 테스트 코드나, 스프링 설정을 목적으로 하는 @Configuration 같은 곳에서는 상관없다.

코드

코드로 작성해 보면 각 필드에 @Autowired를 사용하면 끝이다. 코드가 간결하긴 하다.


4️⃣ 일반 메서드 주입

일반적인 메서드를 통해 주입받는 방법

특징

한 번에 여러 필드의 주입이 가능하다. 하지만 잘 사용되지 않는다.

코드

일반적인 메서드를 작성하고, @Autowired를 지정해 주면 된다. (이렇게 할 바에는 생성자로 하는 게 나을 듯^^)


옵션 처리 ⚙️

주입할 스프링 빈이 없어도 애플리케이션이나 테스트가 동작해야 할 때 옵션 처리를 할 수 있다. 기본적으로 @Autowired만 작성하면 required 옵션의 기본값은 true이기 때문에 자동 주입 대상이 없으면 오류가 발생한다.

자동 주입 방식을 옵션 처리하는 방법은 3가지가 있다.

  • **@Autowired(required = false)** : 자동 주입할 대상이 없으면 메서드 자체가 호출되지 않는다.
  • **org.springframework.lang.@Nullable** : 자동 주입할 대상이 없으면 **null이 주입**된다.
  • **Optional<>** : 자동 주입할 대상이 없으면 **Optional.empty가 주입**된다.

코드

테스트 클래스 안에 임의의 테스트 빈을 만든다.


스프링 컨테이너를 생성할 때 구성 클래스가 아닌 일반적인 클래스를 매개변수로 전달하면 해당 클래스 객체가 빈으로 등록된다.


순서대로 @Autowired(required = false), @Nullable, Optional<>을 사용한 방법이다.


첫 번째 경우는 아예 메서드가 호출이 되지 않으니 출력값이 없고, 두 번째는 null 값, 세 번째는 Optional.empty가 주입되었다.

@NullableOptional<>은 스프링 전반에 걸쳐 지원된다. 예를 들어 생성자 자동 주입에서 특정 필드에만 사용할 수 있다.

profile
좋은 개발자가 되자.

0개의 댓글