Spring DI(Dependency Injection)

henu·2024년 7월 26일

DI(Dependency Injection)은 의존성 주입 혹은 의존 관계 주입이라고도 부른다.

의존성이란

  • 객체를 생성 및 사용함에 있어 의존 관계가 있는 경우

DI(Dependency Injection)


DI란 의존 관계 주입 혹은 의존성 주입이라 불리고, Spring은 3가지 핵심 프로그래밍 모델(AOP, DI, IOC)을 지원하는데, 그 중 하나가 의존 관계 주입(Dependency Injection)이다. Spring은 객체의 의존 관계를 의존 관계 주입을 통해 관리한다. DI는 외부에서 객체 간의 관계(의존성)을 결정해 주는데 객체를 직접 생성하는 것이 아니라 외부에서 생성 후 주입시켜 주는 방식이라고 할 수 있다.
DI를 통해 객체 간의 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮출 수 있다.

Spring에서 DI 방법 3가지


Spring DI 3가지 방법

  • Construct Injection(생성자 주입)
  • Field Injection(필드 주입)
  • Setter Injection(Setter 주입)

Constructor Injection(생성자 주입)


  • 현재 가장 권장되는 의존 관계 주입 방식이다.
  • 하나의 생성자가 존재할 때 필드 주입의 대부분의 단점을 극복한다.
  • Spring 4.3부터는 @Autowired가 생략 가능해서 생성자를 딱 1개 두고, @Autowired를 생략하는 방법을 주로 사용한다.
  • Lombok 라이브러리의 @RequiredArgsConstructor를 함께 사용하면 생성자를 생략 가능해서 코드가 깔끔해진다.
  • 생성자 주입에서만 final 키워드를 사용할 수 있고, 생성자를 통해 주입되는 방식이다.
    - final 키워드를 사용하기 때문에 생성자로 인해 인스턴스가 생성될 때 1번만 할당된다.
  • final 키워드를 사용해서 값이 한 번 할당되면 변경할 수 없기 때문에 객체의 불변성(Immutability)가 보장된다.
  • 초기에 할당되기 때문에 NPE(Null Pointer Exception)이 절대 발생하지 않는다.
public class Injection {
     private InjectionService injectionService;

     public Injection(InjectionService injectionService) {
       this.injectionService = injectionService;
    }
}

여기서 Lombok 라이브러리를 사용하면 생성자를 생략할 수 있음

@RequiredArgsConstructor
public class Injection {

    private final InjectionService injectionService;
    
}

@RequiredArgsConstructor은 final 키워드가 붙은 변수들의 생성자를 만들어준다.

Field Injection(필드 주입)


  • Bean으로 등록된 객체를 사용하고자 하는 클래스에 Field로 선언한 뒤 @Autowired를 붙여주면 자동으로 의존 관계가 주입된다.
  • Spring에서 @Autowired 어노테이션을 사용해서 객체 내 필드에 선언해서 주입하는 방법이다.
  • 간편하게 의존 관계를 주입할 수 있지만 참조 관계를 눈으로 확인하기 어렵고, 순환 참조를 막을 수 없다.
  • 생성자 주입을 제외한 나머지(필드 주입, Setter 주입)은 생성자 이후에 호출되기 때문에 필드에 final 키워드를 사용할 수 없다.
public class Injection {
    @Autowired
    private InjectionService injectionService;
}

필드 주입의 장점

  • 코드가 간결해진다.

필드 주입의 단점

  • Solid 원칙 중 단일 책임 원칙(SRP)을 위반한다.
  • Unit Test가 어렵다.
  • final 키워드를 사용할 수 없다.
    - 불변성이 보장되지 않는다. 객체가 변할 수 있다.

Setter Injection(Setter 주입)

  • Spring에서 @Autowired 어노테이션을 사용해서 Setter 메서드를 통해 주입하는 방법
    - @Autowired는 Field, Setter Method, Constructor에 사용 가능하다.
  • Spring 3.x 버전까지는 DI 권장 방식이었지만 현재는 생성자 주입을 권장한다.
  • NPE(Null Pointer Exception)이 발생할 수 있다.
  • final 키워드를 사용할 수 없다.
public class Injection {
    private InjectionService injectionService;
    @Autowired
    public void setInjectionService( InjectionService injectionService) {
        this.injectionService = injectionService;
    }
}
profile
주니어 백엔드 개발자입니다

0개의 댓글