7. 의존관계 자동 주입

2023. 8. 10. 03:56·Spring/기본

1. 의존관계 주입 방법 3가지

1) 생성자 주입

- 생성자를 통해서 의존관계를 주입하는 방법

- 특징

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

   - 불변, 필수 의존관계에 사용

 

*중요! 생성자가 딱 1개만 있으면 @Autowired를 생략해도 (스프링 컨테이너에 등록된 빈 객체가) 자동 주입된다.

 

2) 수정자 주입 (setter)

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

- 특징

   - 선택, 변경 가능성이 있는 의존관계에 사용

 

cf) @Autowired의 기본 동작은 주입할 대상이 없으면 오류가 발생한다.

      주입할 대상이 없어도 동작하게 하려면 @Autowired(required=false) 로 지정하면 된다.

 

3) 필드 주입

- 외부에서 변경이 불가능해서 테스트 하기가 매우 힘들다.

- DI 프레임워크(Spring)이 없으면 아무것도 할 수 없다.

- 따라서 사용하지 말자!

   - 애플리케이션의 실제 코드와 관계 없는 테스트 코드

   - 스프링 설정을 목적으로 하는 @Configuration 같은 곳에서만 특별한 용도로 사용

 

cf) 순수한 자바 테스트 코드에서는 @Autowired 동작 x

     @SpringBootTest처럼 스프링 컨테이너를 테스트에 통합한 경우에만 가능

 

 

 

 

 

 

2. 의존관계 하는 Spring Bean이 없을 때, 옵션 처리

 

주입할 스프링 빈이 없어도 동작해야 할 때가 있다.

 

1) @Autowired(required=false)

- 자동 주입할 대상이 없으면, 수정자 메서드 자체가 호출되지 않는다.

 

2) org.springframework.lang.@Nullable

- 자동 주입할 대상이 없으면 null이 입력된다.

- 변수 앞에 @Nullable 붙여주면 됨

 

3) Optional<>

- 자동 주입할 대상이 없으면 Optional.empty가 입력된다.

- 변수 앞에 Optional<Type> 붙여주면 됨

 

cf) @Nullable, Optional은 스프링 전반에 걸쳐서 지원되므로, 생성자 자동 주입에서 특정 필드에만 사용해도 된다.

 

 

 

 

 

3. 의존관계 주입할 때, 생성자 주입을 해야 하는 이유

1) 불변

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

   오히려 특정 경우를 제외하고는, 불변해야 한다.

- 수정자 주입을 사용하면, setter를 public으로 열어두어야 한다. (임의로 변경 가능)

- 객체를 생성할 때 1번만 호출되므로, 이후에 호출되는 일이 없다. (불변 설계 가능)

 

2) 누락

- 프레임워크 없이 순수한 자바 코드를 단위 테스트 하는 경우, 의존관계 주입이 누락되는 경우를 방지할 수 있다.

 

3) final 키워드

- 생성자 주입을 사용하면, 필드에 final 키워드를 사용할 수 있다.

   따라서, 생성자에서 혹시라도 값이 설정되지 않는 오류를 컴파일 시점에 막아준다.

 

cf. 수정자 주입, 필드 주입에서는 모두 생성자 이후에 호출되므로,

      필드에 final 키워드를 사용할 수 없다. 오직 생성자 주입에서만 final 키워드를 사용할 수 있다.

 

+. Lombok 라이브러리

- 생성자, 수정자... 코드 최적화

- @RequiredArgsConstructor

   : 자바의 Annotation Processor 기능을 이용해, 컴파일 시점에 생성자 코드를 자동으로 생성해준다.

  

 

 

 

4. 조회 빈이 2개 이상일 때, 자동 의존관계 주입

문제

@Autowired는 타입으로 조회해 자동 의존관계를 주입한다.

그럼, 타입으로 조회했을 때 빈이 2개 이상일 때 어떻게 될까?

 

이 때는 NoUniqueBeanDefinitionException 오류를 발생시킨다.

 

해결방법

: 기본적으로 하위(구체) 타입으로 지정할 수도 있지만, 이는 DIP를 위배하고 유연성이 떨어진다.

   그리고 이름만 다르고, 완전히 똑같은 타입의 스프링 빈이 2개 있을 때 해결이 되지 않는다.

 

 

1) @Autowired 필드명, 빈 이름으로 변경

- @Autowired는 타입 매칭을 시도하고, 이 때 여러 빈이 있으면 필드 이름 · 파라미터 이름으로 빈 이름을 추가 매칭한다.

 

 

2) @Qualifier 사용

- @Qualifier라는 추가 구분자를 붙여주는 방법이다.

  스프링 빈으로 만들 객체에 @Qualifier를 지정해주고, 의존관계 주입 시에 @Qualifier("등록한 이름")를 사용한다.

 

 

동작 과정

1. @Qualifier끼리 매칭

2. 빈 이름 매칭

3. NoSuchBeanDefinitionException 예외 발생

 

cf). @Qualifier는 @Qualifier를 찾는 용도로만 사용하는게 명확하고 좋다.

 

 

3) @Primary 사용

- @Autowired 시에 여러 빈이 매칭되면, @Primary로 등록된 빈 객체가 우선권을 가진다.

 

cf) @Qualifier의 우선순위가 더 높다.

 

 

 

 

5. Annotation 직접 만들기

컴파일 시, 타입 체크를 위해 애노테이션을 직접 만들어보자.

 

 

 

 

 

6. 자동, 수동 빈 등록의 기준

 

자동 빈 등록

: Annotation을 이용한 컴포넌트 스캔

 

수동 빈 등록

: AppConfig.class(@Configuration), 설정 정보 구성

 


 

업무 로직 빈 (자동 빈 등록)

- 웹을 지원하는 Controller, 핵심 비즈니스 로직이 있는 Service, 데이터 계층의 로직을 처리하는 Repository

   보통 비즈니스 요구사항을 개발할 때 추가되거나 변경된다.

 

기술 지원 빈 (수동 빈 등록)

- 기술적인 문제나 공통 관심사(AOP)를 처리할 때 주로 사용된다.

   데이터베이스 연결이나, 공통 로그 처리처럼 업무 로직을 지원하기 위한 하부 기술이나 공통 기술들이다.

 

 

중요! 수동 빈 · 자동 빈 등록할 때 특정 패키지에 같이 묶어둠으로써, 가독성을 편리하게 하는 것이 좋다.

 

'Spring > 기본' 카테고리의 다른 글

9. 빈 스코프  (0) 2023.08.10
8. 빈 생명주기 콜백  (0) 2023.08.10
6. 컴포넌트 스캔  (0) 2023.08.04
5. 싱글톤 컨테이너  (0) 2023.08.04
4. 스프링 컨테이너와 스프링 빈  (0) 2023.08.03
'Spring/기본' 카테고리의 다른 글
  • 9. 빈 스코프
  • 8. 빈 생명주기 콜백
  • 6. 컴포넌트 스캔
  • 5. 싱글톤 컨테이너
wch_t
wch_t
  • wch_t
    끄적끄적(TIL)
    wch_t
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (171)
      • Architecture (0)
      • Algorithm (67)
        • Math (5)
        • Simulation (1)
        • Data Structure (4)
        • DP (7)
        • Brute Fource (10)
        • Binary Search (6)
        • Greedy (2)
        • Graph (11)
        • Mst (1)
        • Shortest path (10)
        • Two Pointer (1)
        • Tsp (3)
        • Union Find (2)
        • Mitm (1)
      • CS (2)
        • 데이터베이스 (5)
        • 네트워크 (5)
      • DB (6)
      • DevOps (17)
        • AWS (9)
        • Docker (1)
        • CI-CD (5)
      • Error (1)
      • Project (0)
        • kotrip (0)
      • Spring (59)
        • 끄적끄적 (5)
        • 기본 (9)
        • MVC 1 (7)
        • MVC 2 (11)
        • ORM (8)
        • JPA 1 (7)
        • JPA 2 (5)
        • Spring Data Jpa (7)
      • Test (2)
      • TIL (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    TempTable
    scope
    response_mode
    백준 3015 파이썬
    docker: not found
    애플
    Sxssf
    form_post
    Merge
    docker
    spring-cloud-starter-aws-secrets-manager-config
    apache poi
    백준 17299 파이썬
    spring-cloud-starter-bootstrap
    view algorithm
    Jenkins
    aws secrets manager
    백준 17289 파이썬
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
wch_t
7. 의존관계 자동 주입
상단으로

티스토리툴바