Dependency Injection in Spring Boot

Jerry·2025년 8월 1일

Spring Boot에서 지원하는 DI 방식

생성자 주입

@Service
public class UserService {

    private final UserRepository userRepository;

    // 생성자를 통해 의존성 주입
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
  • final 사용 가능 → 불변 보장
  • 테스트 코드 작성 쉬움 (DI 프레임워크 없이도 주입 가능)
  • 순환 참조 시점에 컴파일 타임 에러로 확인 가능
  • Spring 4.3+ 부터는 생성자 하나면 @Autowired 생략 가능

필드 주입

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
}
  • 테스트할 때 Mock 객체를 주입하기 어려움
  • 프록시/Reflection으로 테스트 시 주입해야 해서 구조가 약해짐
  • 불변성 보장 불가
  • "강한 결합" 구조가 되기 쉬움

Setter 주입 (옵션성 의존성에 적합)

@Service
public class UserService {

    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
  • 선택적 의존성 주입 가능
  • 순환 참조를 해결할 때 사용하기도 함
  • 잘못 쓰면 객체 생성 시점에 의존성이 빠져서 NPE 발생 가능

사용 팁: Lombok + 생성자 주입

@RequiredArgsConstructor
@Service
public class UserService {

    private final UserRepository userRepository;
}
  • final 필드만 대상으로 생성자 자동 생성
  • 의존성 주입의 가독성 + 안정성 + 생산성 조합
  • 실무에서는 Lombok + 생성자 주입 조합이 사실상 표준

스프링의 DI 흐름

코드에서 의존성 선언 → 스프링이 Bean 생성 및 주입 → 주입된 객체 사용

이 흐름에서 @Configuration@Bean"어떻게 의존 객체(Bean)를 만들지"를 정의하는 핵심 역할을 합니다.

@Configuration

@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService(userRepository());
    }

    @Bean
    public UserRepository userRepository() {
        return new UserRepositoryImpl();
    }
}

이 클래스는 스프링 컨테이너가 Bean을 등록하는 팩토리 역할을 합니다.

  • @Configuration은 내부적으로 프록시 기반의 싱글톤 보장 기능을 제공
  • @Bean 메서드 간 호출 시에도 중복 객체가 생성되지 않음

@Bean

@Bean
public UserService userService() {
    return new UserService(userRepository());
}

@Bean 메서드는 수동 등록된 Bean을 의미합니다.
스프링 컨테이너는 이 메서드가 반환하는 객체를 Bean으로 등록하고 DI 대상에 주입해줍니다.

실제 동작 예시

@Service
@RequiredArgsConstructor
public class OrderService {
    private final PaymentService paymentService;
}
@Configuration
public class PaymentConfig {

    @Bean
    public PaymentService paymentService() {
        return new KakaoPayService();
    }
}

스프링이 OrderService를 생성할 때, PaymentService 타입의 Bean을 찾아
paymentService() 메서드가 반환하는 객체를 주입합니다.

DI 작동 방식 한 줄 요약

스프링 컨테이너가 Bean을 생성할 때, 필요한 의존성을 찾아서 넣어줌
Bean은 기본적으로 싱글톤이라 서버 전체에서 재사용

주입 대상 어노테이션 정리

어노테이션설명
@Component일반적인 컴포넌트 등록
@Service서비스 레이어 등록
@RepositoryDB 레이어 등록 + 예외 변환
@Controller / @RestController웹 요청 처리
profile
Backend engineer

0개의 댓글