일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Java
- Til
- 스파르타코딩클럽
- 스파르타코딩클럽 #개발자 #백엔드
- 레퍼클래스
- 스파르타코딩클럽 #사전캠프
- springboot
- Spring
- 도메인별
- optional
- 자바
- 스터디카페
- 메모리구조
- 스프링부트
- 스파르타사전캠프
- 내일배움캠프
- 패키지구조
- 사전캠프
- til #데이터베이스 #sql
- Framework
- 깃헙
- 계층형
- 깃
- 프레임워크
- jvm
- 키오스크
- 캡슐화
- 요시
- static
- 함바그
- Today
- Total
John's Code Journey
[Spring Boot] IoC/DI 본문
💡 DI(Dependency Injection 의존성 주입)란?
DI(의존성 주입)는 객체 간의 의존 관계를 개발자가 직접 생성하지 않고, 스프링이 자동으로 주입해주는 기능이다.
간단히 말해, 필요한 객체를 "내가 직접 생성"하는 것이 아니라 "스프링이 제공"해주는 것 .
1️⃣ DI 없이 직접 객체 생성하는 경우 (Bad Example)
아래처럼 UserService가 UserRepository 객체를 직접 생성하면 코드 수정이 어렵고, 테스트하기 어려운 코드가 된다.
public class UserService {
private final UserRepository userRepository = new UserRepository(); // 직접 객체 생성 ❌
public void someMethod() {
userRepository.doSomething();
}
}
❌ 직접 객체를 생성하면 생기는 문제점
- UserRepository가 변경되면 UserService도 수정해야 함 (유지보수 어려움)
- 다른 구현체(JpaUserRepository, MemoryUserRepository)로 변경할 때 코드 수정이 필요함
- 단위 테스트에서 Mock 객체를 주입하기 어려움
2️⃣ DI를 활용하여 스프링이 주입하도록 변경 (Good Example)
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
// 생성자를 통해 스프링이 의존성 주입
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void someMethod() {
userRepository.doSomething();
}
}
✅ DI를 적용하면?
- UserRepository 구현체를 쉽게 교체할 수 있음
- 테스트 시 Mock 객체 주입 가능 (즉, 의존성 변경이 쉬움)
- 코드가 더 깔끔하고 유지보수가 쉬워짐
3️⃣ Spring이 DI를 해주는 방식
스프링은 DI를 통해 객체를 직접 생성하지 않고, 스프링 컨테이너가 자동으로 관리 합니다.
✅ DI 방식에는 3가지가 있음
생성자 주입 (권장) | @RequiredArgsConstructor 또는 @Autowired 생성자를 이용한 주입 |
필드 주입 (비추천) | @Autowired를 필드에 직접 붙여서 주입 |
Setter 주입 | @Autowired Setter 메서드를 통해 주입 |
✔ 생성자 주입 (권장)
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository; // final 필드
public void someMethod() {
userRepository.doSomething();
}
}
📌 왜 생성자 주입이 좋을까?
- final을 사용하여 불변성을 유지할 수 있음
- 의존성이 명확하게 드러남
- 테스트 시 Mock 객체를 쉽게 주입할 수 있음
- 순환 참조 문제를 사전에 방지 가능
🎯 DI 정리
✅ DI(의존성 주입)란?
- 객체를 직접 생성하지 않고, 스프링이 대신 객체를 주입하는 것
✅ 왜 DI를 사용할까?
- 코드 유지보수가 쉬워짐
- 유연한 의존성 변경 가능 (테스트, 구현체 교체 등)
- 스프링 컨테이너가 객체 생성을 관리하여 성능과 확장성이 좋아짐
✅ 가장 좋은 DI 방식은?
- "생성자 주입" (@RequiredArgsConstructor or 생성자 + final)
- 필드 주입(@Autowired 필드 사용)은 지양해야 함 (테스트 및 유지보수 어려움)
💡 IoC (Inversion of Control, 제어의 역전)란?
IoC(제어의 역전)란 객체의 생성과 흐름을 개발자가 직접 제어하는 것이 아니라, 프레임워크(스프링)가 대신 제어하는 것이다.
쉽게 말해, 원래 개발자가 하던 객체 생성과 관리 역할을 스프링이 대신하는 것이다.
1️⃣ IoC가 없는 경우 (개발자가 직접 객체를 생성)
아래 코드에서는 UserService가 UserRepository를 직접 생성하고 있습니다.
public class UserService {
private final UserRepository userRepository = new UserRepository(); // 직접 객체 생성 ❌
public void someMethod() {
userRepository.doSomething();
}
}
❌ 직접 객체를 생성하면 문제점
- UserRepository가 변경되면 UserService도 수정해야 함 (유지보수 어려움)
- 객체의 생성과 사용을 개발자가 직접 관리해야 함 → 코드 복잡해짐
- 테스트하기 어려움 (다른 구현체로 쉽게 교체 불가)
2️⃣ IoC를 적용한 경우 (스프링이 객체를 관리)
이제 스프링이 UserRepository 객체를 대신 생성하고 UserService에 주입해 줍니다.
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
// 생성자를 통해 스프링이 의존성 주입 (DI)
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void someMethod() {
userRepository.doSomething();
}
}
✅ IoC 적용 후 장점
- UserRepository 객체를 직접 생성할 필요 없음 → 스프링이 대신 관리
- 코드가 더 깔끔하고 유지보수 쉬움
- 객체 교체가 쉬움 (다른 구현체 MemoryUserRepository, JpaUserRepository로 쉽게 변경 가능)
- 테스트하기 쉬움 (Mock 객체 주입 가능)
3️⃣ IoC의 핵심 개념
1. 객체의 생성과 관리를 스프링이 담당
스프링은 개발자가 직접 객체를 생성하는 대신 스프링 컨테이너(ApplicationContext)가 객체를 생성하고 관리 합니다.
2. 제어의 흐름이 개발자 → 프레임워크로 변경
- 원래는 개발자가 new 키워드로 객체를 직접 생성하고 관리
- IoC 적용 후에는 스프링이 필요한 객체를 알아서 생성하고 관리
4️⃣ IoC와 DI(의존성 주입)의 차이점
IoC (제어의 역전) | 객체 생성과 관리의 주체가 개발자가 아니라, 스프링 컨테이너가 담당 |
DI (의존성 주입) | 스프링이 필요한 객체를 자동으로 주입 |
💡 DI(의존성 주입)는 IoC를 구현하는 방법 중 하나 입니다.
즉, IoC가 "큰 개념"이고, DI는 그중 하나의 방법 입니다.
🎯 IoC 정리
✅ IoC(제어의 역전)란?
- 객체 생성과 관리를 스프링이 대신 해주는 것
- 개발자가 직접 new로 객체를 만들지 않고, 스프링이 알아서 관리
✅ IoC를 적용하면?
- 객체 생성, 생명주기 관리, 주입을 스프링이 자동으로 처리
- 코드가 깔끔해지고 유지보수 쉬워짐
- DI(의존성 주입)를 통해 객체를 유연하게 변경 가능
✅ IoC와 DI의 차이?
- IoC: 객체 관리의 주체가 개발자가 아니라 스프링
- DI: 스프링이 필요한 객체를 자동으로 주입 (IoC의 한 가지 방법)
'IT공부 > Spring Boot' 카테고리의 다른 글
[Spring Boot] 개발 순서 가이드 (0) | 2025.05.09 |
---|---|
[Spring Boot] Validation 검증 (0) | 2025.04.28 |
[Spring Boot] Persistence Context 영속성 컨텍스트 (0) | 2025.04.17 |
[Spring Boot] 생성일 자동 설정 비교 (1) | 2025.04.08 |
[Spring Boot] 기본 흐름 (1) | 2025.04.02 |