Programing_Java
[Spring] new 없이 객체 주입? Autowired와 Component로 배우는 낮은 결합도 본문
✅ Spring DI 개념, 제대로 이해하기
의존 관계 주입(Dependency Injection) == DI
1️⃣ 의존 관계란 무엇인가?
“A는 B에 의존한다”
프로그래밍에서는 곧
👉 A 클래스 안에 B 클래스 타입의 멤버변수가 있다는 뜻
예시:
// SamsungTv는 Remote에 의존
public class SamsungTv {
private Remote remote;
}
2️⃣ 상속보다는 "추상화"로 이해
public interface Remote {
void powerOn();
void powerOff();
void volumeUp();
void volumeDown();
}
// 삼성 리모컨, 엘지 리모컨은 이 Remote 인터페이스를 구현
@Component
public class SamsungRemote implements Remote { ... }
@Component
public class LgRemote implements Remote { ... }
인터페이스가 정의되어 있다는 건?
👉 "구현체를 나중에 꽂아줄 수 있다" 는 뜻
즉, 코드 결합도를 낮출 수 있는 구조
3️⃣ DI에는 3가지 방식이 있다
• 생성자 주입 (Constructor Injection)
• Setter 주입 (Setter Injection)
• 필드 주입 (@Autowired)
4️⃣ 예제 구현
삼성TV는 삼성리모컨을 생성자 주입, 엘지TV는 엘지리모컨을 setter 주입으로 DI
인터페이스 정의
public interface Tv {
void on();
void off();
}
// TV 구현체
@Component
public class SamsungTv implements Tv {
private Remote remote;
@Autowired
public SamsungTv(SamsungRemote remote) {
this.remote = remote;
}
public void on() {
System.out.println("Samsung TV 켭니다.");
remote.powerOn();
}
public void off() {
System.out.println("Samsung TV 끕니다.");
remote.powerOff();
}
}
// // TV 구현체
@Component
public class LgTv implements Tv {
private Remote remote;
@Autowired
public void setRemote(LgRemote remote) {
this.remote = remote;
}
public void on() {
System.out.println("LG TV 켭니다.");
remote.powerOn();
}
public void off() {
System.out.println("LG TV 끕니다.");
remote.powerOff();
}
}
// 리모컨 구현체들
@Component
public class SamsungRemote implements Remote {
public void powerOn() { System.out.println("삼성 리모컨: 전원 ON"); }
public void powerOff() { System.out.println("삼성 리모컨: 전원 OFF"); }
public void volumeUp() {}
public void volumeDown() {}
}
// 리모컨 구현체들
@Component
public class LgRemote implements Remote {
public void powerOn() { System.out.println("LG 리모컨: 전원 ON"); }
public void powerOff() { System.out.println("LG 리모컨: 전원 OFF"); }
public void volumeUp() {}
public void volumeDown() {}
}
5️⃣ Client 테스트 클래스
@Component
public class TvClient {
@Autowired
SamsungTv samsungTv;
@Autowired
LgTv lgTv;
public void test() {
samsungTv.on();
lgTv.on();
}
}
// main
public class App {
public static void main(String[] args) {
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
TvClient client = factory.getBean(TvClient.class);
client.test();
}
}
6️⃣ 핵심 요약
개념 | 의미 | 비유 |
@Component | 스프링 창고에 등록 | Kiwi를 창고에 넣음 |
@Autowired | 등록된 것을 꺼내다 씀 | Apple이 Kiwi를 꺼내 먹음 |
생성자 주입 | 강한 결합도 → 테스트 쉬움 | Apple(과일 마니아)은 Kiwi만 좋아함 |
Setter 주입 | 선택형 | Apple은 입맛에 따라 바꿀 수 있음 |
인터페이스 | 추상화 | "리모컨"이라는 개념만 알고 있음 |
구현체 | 실제 리모컨 | 삼성 리모컨, LG 리모컨 등 |
7️⃣ 마무리
Spring에서 new를 직접 쓰지 않고 의존성을 주입하는 이유는 코드를 더 유지보수 가능하게 만들고 테스트와 확장을 유연하게 하기 위함
의존관계 주입은 무조건 알아야 할 개념
'✅ Spring' 카테고리의 다른 글
🌱 [Spring MVC 구조] DI, Controller, Service, DAO 그리고 DispatcherServlet까지 정리 (0) | 2025.04.20 |
---|---|
✨ Spring MVC에서의 로그인 처리 흐름 : DispatcherServlet부터 Command 객체까지 정복 (0) | 2025.04.17 |
✨ Spring MVC 패턴 정복: DI부터 Controller, DAO까지 한 번에 정리! (0) | 2025.04.16 |
[Spring] Spring vs Spring Boot, 그리고 진짜 중요한 스프링 핵심 개념 총정리 (0) | 2025.04.14 |
[Spring] Spring vs Spring Boot — 왜 Spring Boot를 쓰는가? (0) | 2025.04.14 |