🤝 의존 관계 주입이란?
- 생성자 주입, setter 주입, 필드 주입, 메서드 주입 총 4가지 방법 존재
📚 DI란?
- 필요한 객체를 직접 생성하지 않고, 외부(Spring Container)가 대신 주입해 주는 것
→ 객체 간의 결합도는 낮추고, 유연한 구조를 만들 수 있게 해 줌
1️⃣ 생성자 주입 (가장 권장)
@Autowired 생략 가능🗒️ 예시 코드
@Component
public class MyApp {
private final MyService myService;
// 생성자 주입
@Autowired
public MyApp(MyService myService) {
this.myService = myService;
}
public void run() {
myService.doSomething();
}
}
2️⃣ Setter 주입
@Autowired(required = false)로 설정 가능🗒️ 예시 코드
@Component
public class MyApp {
private MyService myService;
@Autowired
public void setMyService(MyService myService) {
this.myService = myService;
}
}
3️⃣ 필드 주입 (가장 추천되지 않음)
⚠️ 단점
🗒️ 예시 코드
@Component
public class MyApp {
@Autowired
private MyService myService;
public void run() {
myService.doSomething();
}
}
4️⃣ 일반 메서드 주입 (거의 사용하지 않음)
@Autowired를 일반 메서드에 붙여 주입🗒️ 예시 코드
@Component
public class MyApp {
private MyService myService;
@Autowired
public void init(MyService myService) {
this.myService = myService;
}
}
🏗️ 생성자 주입
- 현재는 DI를 가지고 있는 대부분의 Framework가 생성자 주입 방식 권장
✅ 생성자 주입이 가장 권장되는 이유
| 이유 | 설명 |
|---|---|
| 🔒 불변성 | final 필드를 통해 객체 변경 차단 |
| 🧪 테스트 용이성 | 테스트 시 생성자만 호출하면 됨 |
| 🐛 컴파일 타임 오류 | 의존성 빠진 경우 컴파일 시 에러 |
| ☕ 순수 Java에서도 작동 | Spring 없이도 사용 가능 (POJO) |
⚠️ 주의
@Autowired 명시해야 함final 필드는 생성자 주입만 가능 (setter나 필드 주입 불가)🧷
@RequiredArgsConstructor란?
final필드만 모아서 생성자를 자동 생성해 주는 Lombok의 편의 기능
🗒️ 예시 코드
@Component
@RequiredArgsConstructor
public class MyApp {
private final MyService myService;
public void run() {
myService.doSomething();
}
// 자동 생성 코드
// public MyApp(MyService myService) {
// this.myService = myService;
// }
}
✅ 장점
@Autowired 생략 가능