포스트잇

의존성 주입(Dependcy Injection) 본문

스프링

의존성 주입(Dependcy Injection)

생각없는 개발자 2025. 2. 14. 16:35

의존성 주입(DI, Dependency Injection)은 객체 간의 의존 관계를 외부에서 주입해주는 디자인 패턴입니다. 간단한 예로, 우리가 자동차를 만들 때 엔진을 직접 만들 필요 없이 외부에서 조립하듯이, 객체가 필요한 의존성을 직접 생성하지 않고 외부에서 전달받는 방식입니다.


1. 의존성이란?

의존성이란 한 클래스가 다른 클래스의 기능을 필요로 하는 관계를 의미합니다. 예를 들어 Car 클래스가 Engine 클래스를 필요로 한다면, Car는 Engine에 의존하고 있다고 할 수 있습니다.

class Engine {
    void start() {
        System.out.println("엔진이 시작되었습니다.");
    }
}

class Car {
    private Engine engine;

    Car() {
        this.engine = new Engine(); // 직접 객체 생성 (문제점 발생)
    }

    void drive() {
        engine.start();
        System.out.println("자동차가 움직입니다.");
    }
}

위 코드에서 Car 클래스는 Engine을 직접 생성하기 때문에 강한 결합이 발생합니다. 즉, Engine 클래스가 변경되면 Car 클래스도 영향을 받습니다.


2. 의존성 주입의 필요성

의존성 주입을 사용하면 객체 간 결합도를 낮출 수 있습니다. 이를 통해 다음과 같은 장점이 생깁니다.

  • 유연성 증가 : 의존성을 쉽게 변경할 수 있습니다.
  • 테스트 용이성 : 테스트 시 가짜(Mock) 객체를 주입할 수 있습니다.
  • 재사용성 증가 : 객체를 독립적으로 관리할 수 있습니다.

3. 스프링에서의 의존성 주입 방법

3.1 생성자 주입(Constructor Injection)

생성자를 통해 의존성을 주입하는 방식입니다. 가장 권장되는 방법이며, 불변성을 보장할 수 있습니다.

@Component
class Engine {
    void start() {
        System.out.println("엔진이 시작되었습니다.");
    }
}

@Component
class Car {
    private final Engine engine;

    @Autowired // 스프링이 자동으로 주입
    public Car(Engine engine) {
        this.engine = engine;
    }

    void drive() {
        engine.start();
        System.out.println("자동차가 움직입니다.");
    }
}

3.2 필드 주입(Field Injection)

필드에 @Autowired 어노테이션을 붙여 직접 주입하는 방식이지만, 권장되지는 않습니다. 테스트가 어렵고, 객체의 명확한 의존성을 파악하기 어렵기 때문입니다.

@Component
class Car {
    @Autowired
    private Engine engine;
    
    void drive() {
        engine.start();
        System.out.println("자동차가 움직입니다.");
    }
}

3.3 Setter 주입(Setter Injection)

Setter 메서드를 통해 주입하는 방식으로, 선택적 의존성이 필요할 때 유용합니다.

@Component
class Car {
    private Engine engine;

    @Autowired
    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    void drive() {
        engine.start();
        System.out.println("자동차가 움직입니다.");
    }
}

4. 정리

  • 의존성 주입이란 객체의 의존성을 직접 생성하지 않고 외부에서 주입하는 방식
  • DI의 장점 : 결합도 낮추기, 유연성 증가, 테스트 용이성
  • 스프링에서의 DI는 세 종류로 생성자 주입, 필드 주입, Setter 주입이 있다.

'스프링' 카테고리의 다른 글

스프링 부트(Spring Boot)  (0) 2025.02.17
스프링 빈과 빈 스코프  (0) 2025.02.14
스프링 컨테이너와 IoC  (1) 2025.02.14
빌드 파일(build.gradle)  (1) 2024.10.17
Spring이란?  (0) 2024.06.12