1. 의존관계 자동주입이란?
스프링에서의의존관계 자동 주입(Dependency Injection, DI)이란, 개발자가 직접 객체를 생성하지 않고 스프링 컨테이너가 필요한 의존 객체를 자동으로 주입해주는 기능이다.
@Component
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
이처럼 객체 간 결합도를 낮추고 유연하고 테스트 가능한 구조를 만들 수 있게 해준다.
2. 의존관계 주입 방식과 예제
먼저 의존성 인터페이스와 구현체를 정의한다.
public interface PaymentService {
void pay(int amount);
}
@Component
public class KakaoPaymentService implements PaymentService {
public void pay(int amount) {
System.out.println("카카오페이로 결제: " + amount + "원");
}
}
2.1 생성자 주입 (가장 권장되는 방식)
@Component
public class OrderService {
private final PaymentService paymentService;
@Autowired // Spring 4.3+ 에서는 생략 가능
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void processOrder(int amount) {
paymentService.pay(amount);
}
}
장점: 불변성 유지, 테스트 용이성 ↑, DI 실패 시 컴파일 타임 에러 유도
2.2 필드 주입
@Component
public class OrderService {
@Autowired
private PaymentService paymentService;
public void processOrder(int amount) {
paymentService.pay(amount);
}
}
- 장점: 코드 간결
- 단점: 테스트 어려움, 순환참조 발생 시 탐지 어려움
2.3 세터 주입
@Component
public class OrderService {
private PaymentService paymentService;
@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void processOrder(int amount) {
paymentService.pay(amount);
}
}
- 장점: 선택적 의존성에 적합
- 단점: 불변성 깨짐, 누락 가능성 존재
3. @Autowired를 이용한 자동주입
@Component
public class MyService {
@Autowired
private DependencyService dependency;
}
- 타입 기반 매칭
- 동일 타입이 여러 개일 경우 @Qualifier나 @Primary 사용
- @Autowired(required = false) 또는 Optional<>로 선택적 주입 가능
4. 생성자 vs 필드 vs 세터 주입
주입 방식 | 장점 | 단점 | 실무 추천도 |
생성자 주입 | 불변성 보장, 테스트 용이 | 코드 길어짐 | ⭐⭐⭐⭐ |
필드 주입 | 코드 간결 | 테스트 불가, 유지보수 불리 | ⭐ |
세터 주입 | 선택적 주입 가능 | 필수 누락 가능성 | ⭐⭐ |
실무에서는 생성자 주입 + Lombok(@RequiredArgsConstructor) 조합이 가장 많이 쓰인다.
5. 자동주입 시 고려할 점
@Qualifier
@Autowired
@Qualifier("kakaoPaymentService")
private PaymentService paymentService;
@Primary
@Primary
@Component
public class DefaultPaymentService implements PaymentService {}
Optional
@Autowired
private Optional<PromotionService> promotionService;
6. Spring Boot의 자동 구성과 DI
- @SpringBootApplication 내부의 @ComponentScan이 자동으로 Bean을 탐색
- @Component, @Service, @Repository, @Controller 등은 모두 DI 대상
7. Bean의 스코프와 주입 시기
스코프 | 설명 | 객체 생성 시점 |
Singleton (기본) | 애플리케이션당 1개 | 컨테이너 초기화 시 |
Prototype | 요청마다 새로운 객체 | 요청 시 생성 |
Request | HTTP 요청당 | 웹 요청 시 생성 |
Session | 세션당 | 세션 생성 시 |
싱글톤에서 프로토타입 빈 주입 시 Provider 또는 ObjectFactory를 활용해야 함.
8. 실무에서의 Best Practice
- 생성자 주입을 기본으로 통일
- 필수 → 생성자, 선택 → 세터 or Optional
- @Autowired 생략 가능 (생성자 1개일 경우)
- @Qualifier, @Primary를 통한 명확한 주입 처리
- ComponentScan 범위 명확히 지정
9. 요약
항목 | 설명 |
의존관계 주입 | 객체 간 관계를 외부에서 설정 |
추천 주입 방식 | 생성자 주입 + final + Lombok |
DI 핵심 애노테이션 | @Autowired, @Qualifier, @Primary |
장점 | 결합도 감소, 테스트 유리, 유지보수 용이 |
주의할 점 | 순환 참조, 스코프 관리, 의존성 누락 |
반응형
'Backend > Spring(활용)' 카테고리의 다른 글
Spring 기반 Quartz Scheduler 기본 예제 코드(2) - Quartz 설정 정보 (0) | 2025.04.04 |
---|---|
Spring 기반 Quartz Scheduler 기본 예제 코드(1) - 구조적 설계와 흐름 설명 (0) | 2025.04.03 |
Spring Boot에서 MultipartFile 저장 위치 확인 및 활용 방법 (0) | 2025.02.27 |
CORS 오류를 해결하기 위한 다양한 방법 (0) | 2025.02.26 |
HDFS WebHDFS API를 활용한 대용량 파일 다운로드 구현 (Spring Boot + Vue.js 예제) (1) | 2025.02.13 |