[Spring] 의존성 주입(Dependency Injection, DI)

2025. 6. 4. 17:48·Java

개발을 하다 보면 여러 클래스들이 서로 얽혀있는 복잡한 구조를 만나게 된다. 이때 Spring의 의존성 주입은 이런 복잡함을 깔끔하게 정리해주는 핵심 기술이다. 

❓ 정의

의존성 주입(DI)은 클래스가 필요로 하는 의존 객체를 직접 생성하지 않고, 외부에서 주입받아 사용하는 설계 패턴이다. Spring Framework에서는 IoC 컨테이너가 이 역할을 담당하여 객체의 생성과 의존성 관리를 자동으로 처리해준다.

쉽게 말해, 클래스 A가 클래스 B를 사용해야 할 때 A가 직접 B를 new로 생성하는 것이 아니라, Spring이 알아서 B 객체를 만들어서 A에게 전달해주는 방식이다. 예를 들면 음식점에서 요리사가 직접 재료를 구하러 다니는 것이 아니라, 누군가가 필요한 재료를 미리 준비해서 가져다주는 것과 같다.

▶ 기본 사용 예시

강한 결합의 문제점을 먼저 살펴보자.

public class OrderService {
    private final PaymentService paymentService;
    
    public OrderService() {
        this.paymentService = new KakaoPayService();
    }
}

이렇게 작성하면 OrderService는 KakaoPayService에 강하게 의존하게 되어, 다른 결제 서비스로 변경하려면 코드를 직접 수정해야 한다. Spring DI를 사용하면 아래와 같이 개선할 수 있다.

@Service
public class OrderService {
    private final PaymentService paymentService;
    
    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

❗ 사용이유

✅ 결합도 감소

의존성 주입을 사용하면 클래스 간의 결합도가 상당히 낮아진다. 예를 들어, A 클래스가 B 클래스의 구체적인 구현이 아닌 인터페이스에만 의존하게 되면, B의 구현이 변경되어도 A는 영향을 받지 않는다. 이는 전기 제품이 특정 브랜드의 콘센트가 아닌 표준 규격의 콘센트만 알면 되는 것과 같은 원리다.

✅ 테스트 용이

DI를 사용하면 테스트할 때 실제 의존 객체 대신 Mock 객체를 주입할 수 있어 단위 테스트가 훨씬 쉬워진다. 실제 데이터베이스 대신 가짜 데이터베이스를 사용해서 테스트하는 것처럼, 외부 의존성 없이 독립적인 테스트가 가능하다.

✅ 유지보수성 증가

코드의 변경이 다른 부분에 미치는 영향을 최소화할 수 있어 유지보수가 훨씬 수월하다. 새로운 기능을 추가하거나 기존 기능을 수정할 때도 관련된 클래스만 수정하면 되므로 편리하다.


💥 주의

1️⃣ 순환 참조 문제

A가 B를 참조하고 B가 다시 A를 참조하는 순환 참조가 발생할 수 있다.

 -> 생성자 주입을 사용하면 컴파일 시점에 이런 문제를 발견할 수 있다.

2️⃣ 동일 타입 빈 충돌

같은 타입의 빈이 여러 개 등록되어 있으면 어떤 것을 주입할지 Spring이 판단하지 못한다.

 -> @Qualifier나 @Primary 어노테이션을 사용해서 명시적으로 지정해야 한다.


💠 예시

1️⃣ 생성자 주입

@Service
public class UserService {
    private final UserRepository userRepository;
    private final EmailService emailService;
    
    public UserService(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }
}

2️⃣ 세터 주입

@Service
public class UserService {
    private UserRepository userRepository;
    
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

3️⃣ 필드 주입

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

 

▶ 사용 예시

@RestController
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;
    
    @GetMapping("/users/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
}

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
    private final EmailService emailService;
    
    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new UserNotFoundException("User not found"));
    }
}

앞으로 Spring을 사용할 때는 항상 의존성 주입을 염두에 두고 설계하는 습관을 기르는 것이 중요할 것 같다. 그러면 더 깔끔하고 유지보수하기 쉬운 코드를 작성할 수 있을 것이다!

[참고]

더보기
https://okeybox.tistory.com/419

https://dev-coco.tistory.com/70

https://kim-oriental.tistory.com/32#google_vignette

 

 

 

 

 

 

 

저작자표시 비영리 변경금지 (새창열림)

'Java' 카테고리의 다른 글

Spring Security와 ThreadLocal  (0) 2025.08.29
'Java' 카테고리의 다른 글
  • Spring Security와 ThreadLocal
버그잡는고양이발
버그잡는고양이발
주니어 개발자입니다!
  • 버그잡는고양이발
    지극히평범한개발블로그
    버그잡는고양이발
  • 전체
    오늘
    어제
    • 분류 전체보기 (382)
      • React (16)
      • Next.js (5)
      • Javascript (5)
      • Typescript (4)
      • Node.js (2)
      • Cs (16)
      • 트러블 슈팅 (5)
      • Html (1)
      • Css (3)
      • Django (0)
      • vue (0)
      • Java (2)
      • Python (0)
      • 독서 (1)
      • 기타 (3)
      • 백준 (192)
      • swea (31)
      • 프로그래머스 (30)
      • 이코테 (4)
      • 99클럽 코테 스터디 (30)
      • ssafy (31)
      • IT기사 (1)
  • 블로그 메뉴

    • 홈
    • 태그
  • 인기 글

  • 태그

    코딩테스트준비
    99클럽
    Til
    개발자취업
    항해99
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
버그잡는고양이발
[Spring] 의존성 주입(Dependency Injection, DI)
상단으로

티스토리툴바