의존성(Dependency)
한 객체(클래스)가 다른 객체(클래스)를 사용할 때 생기는 관계
ㅡ> 의존성 = 내가 제대로 일하려면 꼭 필요한 도구/객체
"A가 B 없이는 제대로 동작할 수 없는 상태"
즉, A가 B에 의존하고 있다고 말해요.
🎯 UserService 예시로 설명
@Service
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder passwordEncoder;
@Autowired
public UserService(UserRepository userRepository, BCryptPasswordEncoder passwordEncoder){
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
}
- UserService는 UserRepository 없이는 유저를 DB에 저장 못함 → 의존
- UserService는 BCryptPasswordEncoder 없이는 비밀번호 암호화 못함 → 의존
의존성 주입 (DI)
(P) 객체 간 관계 많아지면 유지보수/테스트 어려움
(S) Spring이 의존성 주입으로 관리
■ 의존성 주입 (DI)
ㅡ> 필요한 객체(의존성)를 내가 직접 만드는 게 아니라, 외부에서 "주입"해주는 것.
ㅡ> Spring이 필요한 의존성들을 자동으로 객체에 넣어줌 (주입). → 그래서 @Autowired를 사용하는 것!
요리사 비유
1️⃣ 의존성이 없는 상태
요리사(UserService)가 요리(회원가입)를 하려면:
- 식재료 창고(UserRepository)
- 칼(BCryptPasswordEncoder)
둘 다 필요함.
👉 그런데 요리사가 직접 마트 가서 재료 사고, 칼도 직접 제작함.
➡️ 문제점:
- 요리사가 창고와 칼 만드는 방법까지 알아야 함.
- 나중에 창고 바꾸거나, 칼 종류 바꾸려면 코드 다 고쳐야 함.
2️⃣ 의존성 주입 상태
요리사는 "필요한 것만 요구"하고
- 재료 창고랑 칼은 **외부에서 미리 준비해서 건네줌.**
👉 요리사는 그냥 주어진 도구로 요리만 집중하면 됨.
코드 예시
❌ 직접 만들기 (의존성 직접 관리, 안 좋은 방법)
public class UserService {
private UserRepository userRepository = new UserRepository(); // 직접 생성
private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 직접 생성
public void register() {
// 비즈니스 로직...
}
}
문제:
→ UserRepository, BCryptPasswordEncoder의 구체적인 생성 방법을 UserService가 알아야 함.
✅ Spring의 의존성 주입 (DI)
@Service
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder passwordEncoder;
@Autowired // Spring이 알아서 주입해줌!
public UserService(UserRepository userRepository, BCryptPasswordEncoder passwordEncoder){
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
}
- UserService는 "나한테 UserRepository랑 BCryptPasswordEncoder 주세요"만 함.
- 어떻게 만들지, 어떤 구현체인지 신경 안 씀.
- Spring이 알아서 필요한 객체를 생성하고, 넣어줌!
결론
"내가 필요한 도구(의존성)를 직접 만들지 않고, 외부(SPRING)가 알아서 주입해주니 → 나는 내 일(비즈니스 로직)에만 집중할 수 있다!"
스프링 프레임워크 개발자는 객체 생성 방법을 다 알아야 하지만
ㅡ> 우리는 어노테이션만 달면 됨
DI 장점
ㅡ> 객체 생명주기(언제 생성, 언제 파괴) 스프링이 관리
ㅡ> 객체 업캐스팅 방식으로 교체하고 싶을 때, 빈에서 바꾸면 프로젝트 전체에 적용 됨
객체 교체
ㅡ> 만약 암호화 방식( public PasswordEncoder )을 바꾸고싶다면, AppConfig에서 빈에서 수정해주면 프로젝트 전체에 적용 됨
ㅡ> new 방식으로 개발자가 직접 주입하면, 암호화 쓰는 객체 전부 개발자가 수정해줘야 함...
'프레임워크 > Spring' 카테고리의 다른 글
@Controller VS @RestController (0) | 2025.03.26 |
---|---|
REST API (0) | 2025.03.26 |
Spring Framework 개념 구조화 (0) | 2025.03.23 |
Controller, Service, Repository 패턴 (0) | 2025.03.18 |
[김영한] 스프링 입문(5) - 회원 관리 예 - MVC 개발 (1) | 2024.08.30 |