의존성 주입

의존성 주입 (Dependency Injection)

빈(Bean)을 만들고 그 사이 의존 관계를 엮는 일은 스프링 애플리케이션의 가장 기본적인 동작이에요. Spring Boot는 이 과정을 스프링 프레임워크가 가진 기법 그대로 쓰도록 열어두는데요, 여러분이 신경 쓸 일을 최소화하기 위해 몇 가지 권장 패턴을 제시해요. 이 글에서는 빈을 정의하고 주입하는 표준적인 방법, 특히 생성자 주입을 중심으로 살펴볼게요.

출처: Spring Beans and Dependency Injection (Spring Boot Reference Documentation)

빈 정의와 주입의 기본

스프링 프레임워크가 제공하는 표준 기법은 그대로 사용할 수 있어요. 다만 스프링 팀은 의존성을 생성자 주입으로 연결하고, @ComponentScan으로 빈을 찾는 방식을 권장해요. 생성자 주입을 쓰면 필드를 final로 선언할 수 있어서, 한번 주입된 의존성이 이후에 바뀌지 않는다는 게 코드 자체에 드러나요.

다음 예시는 생성자 주입으로 필수 의존성인 RiskAssessor 빈을 받는 @Service 빈이에요.

import org.springframework.stereotype.Service;

@Service
public class MyAccountService implements AccountService {
    private final RiskAssessor riskAssessor;

    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }
    // ...
}

생성자가 하나뿐이라면 스프링이 알아서 사용할 생성자를 고르지만, 생성자가 둘 이상이라면 스프링이 어떤 생성자를 쓸지 알려줘야 해요. 이때 @Autowired로 사용할 생성자를 표시하면 돼요.

import java.io.PrintStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyAccountService implements AccountService {
    private final RiskAssessor riskAssessor;
    private final PrintStream out;

    @Autowired
    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
        this.out = System.out;
    }

    public MyAccountService(RiskAssessor riskAssessor, PrintStream out) {
        this.riskAssessor = riskAssessor;
        this.out = out;
    }
    // ...
}

알아두면 좋은 점

  • 생성자 주입을 쓰면 riskAssessor 필드를 final로 표시할 수 있어요. 이후에 다시 변경될 수 없다는 사실이 타입에 그대로 남는 셈이죠.
  • 빈을 찾는 방법과 주입 방식을 더 깊이 이해하려면 스프링 프레임워크의 문서를 함께 보는 게 좋아요. Spring Boot는 자동 설정을 통해 여러분이 작성한 빈과 스프링 내부 빈을 자연스럽게 연결해요.

더 알아보기 (Learn more)