Back-end/SpringBoot

의존성 주입이란 무엇일까?

xeunnie 2024. 6. 23. 17:45
728x90
반응형

의존성 주입(Dependency Injection, DI) 이란?
간단히, 객체 간의 의존 관계를 외부에서 결정하고 주입하는 것을 말한다.

객체 지향 설계 원칙 중 하나인 의존 관계 역전 원칙(Dependency Inversion Principle, DIP)을 구현하는 방법 중 하나다.

의존성과 의존 관계

  • 의존성(Dependency)
    하나의 객체가 다른 객체를 사용하는 경우, 이를 의존성이라고 한다.
    예를 들어, 서비스 객체가 리포지토리 객체를 사용한다면 서비스 객체는 리포지토리 객체에 의존성을 가지는 것이다.
  • 의존 관계(Dependency Relationship):
    객체 간의 의존성이 형성되는 관계를 의존 관계라고 한다.
    의존 관계가 형성되면 한 객체의 변경이 다른 객체에 영향을 미칠 수 있다.

의존성 주입이 필요한 이유

  1. 결합도 감소
    의존성 주입을 통해 객체 간의 결합도를 줄일 수 있다.
    또한 객체 간의 직접적인 의존성을 외부에서 주입함으로써, 코드의 유연성과 재사용성이 증가한다.
  2. 테스트 용이성
    의존성 주입을 사용하면 테스트에서 모의(mock) 객체를 주입할 수 있디.
    객체의 독립적인 단위 테스트(Unit Test) 수행은 코드의 품질 향상과 버그 감소에 도움이 된다.
  3. 재사용성 증가
    의존성 주입을 사용하면 독립적인 컴포넌트들을 재사용할 수 있다.
    각각의 컴포넌트가 자신이 필요로 하는 의존성을 직접 만들지 않고 주입받기 때문에, 코드의 재사용성이 높아진다.

의존성 주입(Dependency Injection, DI) 방법

의존성 주입에는 세 가지 방법이 있다.
생성자 주입(Constructor Injection), Setter 주입(Setter Injection), 필드 주입(Field Injection)이다.

1. 생성자 주입(Constructor Injection)

생성자 주입은 의존성을 객체 생성 시점에 주입하는 방식이다.

  • 특징:
    • 생성자를 통해 의존성을 주입받는다. 따라서 객체가 생성될 때 반드시 필요한 의존성을 가지고 있어 한다.
    • 한 번 생성된 객체의 의존성이 변경되지 않기 때문에 주로 불변(immutable) 객체를 만드는 데에 사용된다.
    • 코드에서 의존성을 명시적으로 표현할 수 있어 가독성이 높다.
  • 예시:
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) { 
        this.userRepository = userRepository; 
    } 
    // UserService의 다른 메서드들에서 userRepository를 사용 
}

2. Setter 주입(Setter Injection)

Setter 주입은 의존성을 Setter 메서드를 통해 주입하는 방식이다.

  • 특징:
    • Setter 메서드를 통해 필요할 때마다 의존성을 변경할 수 있다. 따라서 선택적으로 의존성을 주입받을 수 있다.
    • 객체 생성 후에도 동적으로 의존성을 변경할 수 있어 유연성이 높다.
    • 다수의 의존성이 있고 특정 의존성만을 변경하고자 할 때 유용하다.
  • 예시:
public class UserService {
    private UserRepository userRepository;

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository; 
    } 
    // UserService의 다른 메서드들에서 userRepository를 사용 
}

3. 필드 주입(Field Injection)

필드 주입은 의존성을 클래스의 필드에 직접 주입하는 방식이다.

  • 특징:
    • 주로 프레임워크에서 사용되며, @Autowired@Inject와 같은 어노테이션을 사용하여 주입받는다.
    • 코드가 간결하고 직관적이지만, 외부에서 변경이 어려워 테스트 용이성이 떨어질 수 있다.
    • 일반적으로는 단위 테스트에서는 사용을 지양하고, 주로 프레임워크에서 지원하는 경우에 사용한다.
  • 예시:
public class UserService {
    @Autowired
    private UserRepository userRepository;
    // UserService의 다른 메서드들에서 userRepository를 사용 
}

어떤 방법을 선택해야 할까?

보통은 생성자 주입을 선호하며, 그렇지 않을 때에 한하여 Setter 주입을 사용하는 것이 일반적인 권장 사항이다.
필드 주입은 특정한 경우에만 적합하므로 사용 시 주의가 필요하다.

  • 생성자 주입
    의존성이 필수적으로 필요한 객체 생성 시점에 모두 주입받아야 할 때 유용하며 코드의 안정성과 가독성을 높일 수 있다.
  • Setter 주입
    선택적으로 의존성을 주입받아야 할 때, 동적으로 변경해야 할 때 유용하다.
    또한, 다수의 의존성 중 특정 의존성만을 변경하고자 할 때 유용하다.
  • 필드 주입
    코드가 간결하고 직관적이지만, 외부에서 의존성을 직접 변경하기 어렵고 테스트 용이성이 떨어질 수 있다.
    프레임워크에서 제공하는 경우에 사용하는 것이 좋다.
728x90
반응형