[Spring] DI (Dependency Injection)

wujin·2024년 7월 5일

의존성 주입 (DI:Dependency Injection)

  • 의존 관계 주입 또는 의존성 주입이라 불린다.
  • Spring의 3가지 핵심 기술 중 하나로, 객체 간의 의존 관계를 외부에서 설정하여 주입하는 방법
  • DI를 통해 객체를 직접 생성하는 것이 아니라 외부에서 생성된 객체를 주입시키므로, 유연성을 높이고 결합도를 낮추는 장점이 있다.

DI 3가지 방법

1. Constructor Injection (생성자 주입)

  • 가장 권장되는 방식으로, 생성자를 통해 의존성을 주입되는 방식
  • 생성자를 통해 주입되기 때문에 한 번 할당되면 변경이 불가능하고 불변성을 유지할 수 있다.
  • final 키워드를 사용할 수 있어 불변성(Immutobillty)을 보장
  • 초기에 할당되기 때문에 NPE(Null Pointer Exception)이 발생하지 않음
  • 보통 lombok의 @RequiredArgsConstructor를 함께 사용하여 코드를 간결하지 작성할 수 있다.
public class Injection {

    private final InjectionService injectionService;

    // 생성자 DI
    public Injection(InjectionService injectionService) {
        this.injectionService = injectionService;
    }
}

/**
 * 롬복(Lombok) 라이브러리를 사용
 */
@RequiredArgsConstructor
public class Injection {

    private InjectionService injectionService;
    
}

2. Setter Injection (수정자 주입)

  • Setter 메서드를 통해 의존성을 주입하는 방식
  • Spring에서는 @Autowired 어노테이션을 사용하여 Setter 메서드를 자동으로 호출하여 의존성을 주입
    • @Autowired 어노테이션은 Field, Setter, Method, Constructor에 사용이 가능
  • 필드에 final 키워드를 사용할 수 없으며, 객체 생성 이후에 Setter 메서드가 호출(생성자 이후에 호출)되므로 NPE(Null Point Exception) 발생할 수 있다.
  • Spring 3.x 버전까지는 DI 권장 방식이였다.
public class Injection {

    private InjectionService injectionService;

    // Setter DI
    @Autowired
    public void setInjectionService(InjectionService injectionService) {
        this.injectionService = injectionService;
    }
}

3. Field Injection (필드 주입)

  • Bean으로 등록된 객체를 Field에 직접 @Autowired 어노테이션을 사용하여 의존성을 주입하는 방식
  • 가장 간단하지만, 순환 참조와 같은 문제를 발생시킬 수 있고, 의존 관계를 명확하게 알기 어렵다는 단점이 있다.
  • SOILD 원칙 중 단일 책임 원칙(SRP)을 위반할 가능성이 있으며, Unit Test가 어려워 질 수 있다.
  • final 키워드를 사용할 수 없다.
public class Injection {

    @Autowired
    private InjectionService injectionService;
}

결론

  • Spring 개발 환경에서는 생성자 주입(Constructor Injection)을 권장한다.
  • 생성자 주입은 객체를 한 번 생성되면 변경되지 않도록 보장할 수 있고, 불변성을 유지할 수 있다.
  • 수정자 주입(Setter Injection)은 선택적으로 사용하며, 필드 주입(Field Injection)은 피하는 것이 좋다.
  • 의존 관계는 한 번 설정되면 일반적으로 애플리케이션이 종료될 때까지 변경되지 않아야 하므로, Setter 메서드를 공개적으로 열어두는 것은 지양해야 한다.

참고자료
https://backendcode.tistory.com/249#head4

0개의 댓글