[spring] 자동 의존관계 주입 방법

괭이밥·2022년 11월 5일

spring

목록 보기
3/10
post-thumbnail

🔎 목차

  1. 자동 의존 관계 주입
  2. 생성자 주입
  3. 수정자 주입
  4. 필드 주입
  5. 일반 메서드 주입

📌 자동 의존관계 주입

@Component를 통해 스프링 빈을 등록하면 의존 관계 주입을 직접 해줄 수 없으므로 자동 의존관계 주입을 해주어야 한다.

자동 의존관계 주입 방법 4가지

1. 생성자 주입

  • 생성자를 통해 의존관계 주입한다.
  • 생성자 위에 @Autowired를 추가한다.
  • 컴포넌트 스캔을 통해 스프링 빈 등록될 때 생성자 호출하면서 의존관계가 주입된다.
    • 본래 스프링 컨테이너 생성 과정
      1. 스프링 빈 등록
      2. 의존관계 주입
    • 생성자를 통한 자동 생성자 주입의 경우 스프링 컨테이서 생성 과정
      1. 스프링 빈 등록과 동시에 의존관계 주입

2. 수정자 주입

  • setter를 통해 의존관계 주입한다.
  • 관례상 setter명을 set필드명으로 한다.

3. 필드 주입

  • 필드에 바로 주입한다.
  • 필드에 바로 @Autowired를 추가한다.

4. 일반 메서드 주입

  • 일반 메서드를 통해 주입한다.
  • 메서드 위 @Autowired를 추가한다.


🍃 생성자 주입

생성자 주입

  • 생성자를 통해 의존관계 주입한다.
    • 생성자 위에 @Autowired를 추가
  • 만약 생성자가 1개라면 @Autowired 생략이 가능하다.

특징

  • final 키워드를 사용할 수 있다.
    • 불변 의존관계에 자주 사용
  • 생성자 호출 시점에 의존관계 주입된다. -> 딱 한번만 호출된다.
  • 빈 생성과 동시에 의존관계 주입이 일어난다.
    • 스프링 컨테이너는 빈 생성 -> 의존관계 주입으로 두 단계가 나뉘지만 생성자 주입의 경우 동시에 일어남
  • 값 세팅 후 변경이 불가능하다.

코드 예시

@Component
public class MemoryMyRepository implements MyRepository {

    private final MyBean myBean;

    @Autowired
    public MemoryMyRepository(MyBean myBean){
        this.myBean = myBean;
    }
}


🍃 수정자 주입

수정자 주입 - setter

  • setter를 통해 의존관계 주입한다.
    • setter 위에 @Autowired 추가
    • 변경의 가능성이 있음
  • 보통 set메서드명으로 이름을 짓는다.

특징

  • setter는 public으로 열어둔다. -> 변경의 가능성이 있다.
  • 의존관계 주입 단계 때 주입이 일어난다.
  • 생성자와 수정자 모두 있어도 수정자 호출한다.
    • 스프링이 싱글톤을 보장하므로 같은 인스턴스 호출된다.

코드 예제

@Component
public class MemoryMyRepository implements MyRepository {

    private MyBean myBean;

    @Autowired
    public void setMyBean(MyBean myBean) {
        this.myBean = myBean;
    }
}

참고! @Autowired 는 주입할 대상이 없으면 오류 발생한다. 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false) 를 활용하면 된다.



🍃 필드 주입

필드 주입

  • 선언 필드에 바로 주입한다.
    • 필드에 @Autowired추가
  • final 키워드 사용이 불가능하다.

특징

  • 코드가 매우 간결해진다.
  • DI 프레임워크에 의존적이다.
  • 외부에서 변경 불가능하다.
    • 순수한 자바 코드 테스트에서 NullPointerException 에러 발생한다.
      • DI 프레임워크가 의존관계 주입해주어야 하는데 순수한 자바 코드에는 없기 때문!
    • 생성자를 통해 의존관계 주입하여 테스트를 진행하면 된다. -> 생성자 추가 코드 발생
  • 간단한 테스트에서만 쓰는 것을 추천 (DI 프레임워크 환경)

코드 예제

@Component
public class MemoryMyRepository implements MyRepository {

	@Autowired private MyBean myBean;
    
}


🍃 일반 메서드 주입

메서드 주입

  • 의존관계 주입하려는 메서드를 직접 만들 수 있다.
    • 해당 메서드 위에 @Autowired 추가

특징

  • 한번에 여러 필드 주입 가능하다.ㅣ
  • 잘 사용하지 않는다.
    • 일반 메서드 코드를 추가하기보다 생성자, 수정자를 통한 의존관계 주입이 더 깔끔하다.

@Component
public class MemoryMyRepository implements MyRepository {

    private MyBean myBean;
	
    @Autowired
    public void init(MyBean myBean){
        this.myBean = myBean;
    }

}


추가로 어떤 방법으로 의존관계 주입을 하면 좋을까?

스프링을 포함한 DI 프레임워크 대부분은 생성자 주입을 권장한다! 그 이유는 다음과 같다.

불변

  • 대부분 의존관계는 애플리케이션 종료 시점전까지 변하면 안 된다.
    • 대부분 의존관계 주입 후 변경하는 일은 거의 없다.
  • 수정자 주입, 일반 메서드 주입의 경우 메서드를 public으로 열어야 한다. 이는 수정의 위험성이 있다.

누락

  • 필요한 의존관계를 누락없이 진행할 수 있다.
  • 생성자 주입의 경우 필요한 의존관계를 바로 알 수 있다.
    • 혹여나 빠트릴 경우 컴파일 에러로 바로 알 수 있다.
    • 수정자 주업의 경우 널포인트 에러가 발생할 수 있다. 이는 어떤 의존관계가 필요한지 한번에 알기 쉽지 않다.

final 키워드

  • final
    • 생성하면 바뀌지 않는다. -> 불변
    • final을 사용한 필드는 초기화를 해주거나 생성자를 통해 값을 넣어야 한다.
    • 값이 설정되지 않는다면 컴파일 에러가 발생한다. -> 누락방지
  • final 키워드를 사용할 경우 불변과 누락을 동시에 지킬 수 있다.

출처
인프런 '스프링 핵심 원리 - 기본편' 강의

profile
개발도 하고 싶은 클라우드 엔지니어

0개의 댓글