Post

DI (Dependency Injection)

DI(Dependency Injection)는 객체 간의 의존성을 Spring Framework가 관리하여 객체 생성 및 의존성 주입을 처리하는 디자인 패턴입니다. DI는 Spring의 핵심 개념 중 하나로, 코드의 결합도를 낮추고 유연성과 테스트 가능성을 높입니다.

DI의 주요 개념

  1. 의존성 (Dependency):
    • 클래스가 다른 클래스 또는 객체에 의존할 때, 해당 의존성을 Dependency라고 합니다.
    • ex) A 클래스가 B 클래스의 기능을 사용하려면 B 클래스의 객체가 필요합니다.
  2. 의존성 주입 (Injection):
    • 객체의 의존성을 코드 내부에서 명시적으로 생성하지 않고, 외부에서 전달받는 방식입니다.
    • 스프링 컨테이너가 객체의 의존성을 관리하고 필요한 곳에 자동으로 주입합니다.

DI의 이점

  1. 결합도 감소 (Low Coupling):
    • 객체 간의 직접적인 의존을 제거하여 코드의 변경 가능성을 줄입니다.
  2. 유지보수 용이성:
    • 객체 간의 관계가 명확하고, 변경에 따른 영향을 최소화할 수 있습니다.
  3. 테스트 용이성:
    • Mock 객체를 사용하여 독립적으로 테스트할 수 있습니다.
  4. 가독성 및 재사용성:
    • 객체 관리가 쉬워지고, 재사용 가능한 구조를 제공합니다.

Spring에서의 DI 구현 방식

1. 생성자 주입 (Constructor Injection):

  • 의존성을 생성자를 통해 주입합니다, 의존성이 불변(Immutable)이며, 객체 생성 시 필수 의존성을 보장합니다.
1
2
3
4
5
6
7
8
9
@Component
public class ServiceA {
    private final ServiceB serviceB;

    @Autowired
    public ServiceA(ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

2. 세터 주입 (Setter Injection):

  • 의존성을 세터 메서드를 통해 주입합니다, 선택적 의존성을 처리할 수 있습니다.
1
2
3
4
5
6
7
8
9
@Component
public class ServiceA {
    private ServiceB serviceB;

    @Autowired
    public void setServiceB(ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

3. 필드 주입 (Field Injection):

  • 필드에 직접 의존성을 주입합니다. 단, 의존성 변경이 어려워 테스트나 유지보수가 힘들 수 있습니다.
1
2
3
4
5
@Component
public class ServiceA {
    @Autowired
    private ServiceB serviceB;
}

DI를 설정하는 방법

Java 기반 설정 (Java Config):

  • @Configuration과 @Bean을 사용하여 의존성을 정의합니다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    @Configuration
    public class AppConfig {
      @Bean
      public ServiceA serviceA(ServiceB serviceB) {
          return new ServiceA(serviceB);
      }
    
      @Bean
      public ServiceB serviceB() {
          return new ServiceB();
      }
    }
    

어노테이션 기반 방식 (Annotation):

  • @Autowired, @Component 등을 사용하여 의존성을 자동 주입합니다.
    1
    2
    3
    4
    5
    
    @Component
    public class ServiceA {
      @Autowired
      private ServiceB serviceB;
    }
    

Spring DI와 IoC

DI는 Spring의 IoC(Inversion of Control) 컨테이너에서 실행됩니다. IoC는 객체 생성 및 생명주기 관리를 개발자가 아닌 컨테이너가 제어하도록 위임하는 개념입니다. DI는 IoC의 구체적인 구현 방식 중 하나입니다.

DI의 실제 활용

DI는 레이어드 아키텍처(Controller, Service, Repository 등)에서 레이어 간의 의존성을 주입하고 관리하는 데 효과적입니다. 이를 통해 비즈니스 로직(Service)과 데이터 액세스 로직(Repository)을 분리하여 유지보수성과 테스트 용이성을 제공합니다.

This post is licensed under CC BY 4.0 by the author.