개발 모음집/Spring
Spring IoC, DI 란?
wonos
2025. 6. 22. 08:22
💡 1. IoC (Inversion of Control) — 제어의 역전
✅ 정의
- 객체의 생성, 사용, 소멸 등 제어 흐름의 주체가 개발자가 아니라 외부(컨테이너, 프레임워크)로 넘어가는 구조.
- 즉, “개발자가 필요할 때 객체를 생성하여 호출”하는 것이 아니라, “프레임워크가 객체를 생성하고 실행 흐름을 제어”한다는 뜻.
✅ 대표 예시
- 서블릿: 우리가 doGet/doPost를 직접 호출하지 않음. 톰캣 같은 WAS가 호출.
- 스프링: @Component, @Controller, @Service, @Repository 등으로 빈 등록 시, 직접 객체 생성하지 않고 컨테이너가 제어.
💡 2. DI (Dependency Injection) — 의존성 주입
✅ 정의
- 클래스 간의 의존 관계를 직접 생성(new) 하지 않고, **외부(스프링 컨테이너)에서 주입.
- 클래스가 사용하는 객체를 외부에서 만들어서 넣어줌으로써, 유연성과 테스트 용이성 확보.
✅ 방식
- 생성자 주입 (추천)
- 필드 주입 (지양)
- 세터 주입
✅ 예시
@Component
public class OrderService {
private final OrderRepository orderRepository;
@Autowired
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
→ 개발자가 OrderRepository 객체를 생성하지 않음.
→ 스프링 컨테이너가 알아서 주입.
💡 3. IoC/DI로 달성되는 효과
항목 | 설명 |
---|---|
결합도 감소 | 구현체가 아닌 인터페이스에 의존 → 교체 용이 |
테스트 용이성 | Mock 객체로 쉽게 주입 가능 |
확장성 | 전략 패턴 등과 결합 시, 새 기능 추가 쉬움 |
프레임워크 중심 개발 | 개발자는 “어디서 호출되나”가 아닌 “무엇을 할 것인가”에 집중 가능 |
## 💡 4. 그럼 이게 왜 중요할까? → ## AOP와 연결 |
스프링은 IoC/DI를 통해 객체 간 의존 관계를 유연하게 만들었다. 그런데 객체 간 관계만 잘 묶는다고 좋은 시스템이 되진 않음.
시스템에는 공통적으로 처리해야 할 관심사(Cross-cutting concerns)가 존재함. 예를 들어:
- 트랜잭션 처리
- 로깅
- 보안 체크
- 모니터링
- 성능 측정
이러한 관심사를 비즈니스 로직과 분리하려면?
👉 바로 AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍) 사용!
💡 5. AOP (Aspect-Oriented Programming) 개요
용어 | 설명 |
---|---|
Aspect | 공통 관심사 모듈 (ex. 로그, 트랜잭션 처리) |
Advice | 언제 어떤 작업을 할지 정의 (ex. 메서드 실행 전/후) |
JoinPoint | Advice가 적용 가능한 지점 (ex. 메서드 호출 시점) |
Pointcut | JoinPoint 중 Advice가 실제로 적용되는 지점 |
Weaving | 실제 로직에 Aspect가 끼워지는 행위 (스프링은 프록시 기반 Weaving 사용) |
## 💡 6. 스프링에서 AOP는 어떻게 동작할까? |
스프링 AOP는 기본적으로 프록시 기반 AOP를 제공함:
- @Aspect 어노테이션과 @Around, @Before, @After 등을 이용해 공통 로직 정의
- @EnableAspectJAutoProxy로 AOP 활성화
@Aspect
@Component
public class LogAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed(); // 실제 대상 메서드 실행
long end = System.currentTimeMillis();
System.out.println(joinPoint.getSignature() + " executed in " + (end - start) + "ms");
return proceed;
}
}
✅ 핵심 요약
핵심 키워드 | 설명 |
---|---|
IoC | 프레임워크가 객체 생성 및 실행 흐름 제어 |
DI | 의존 객체를 직접 만들지 않고 주입받음 |
AOP | 공통 관심사 분리를 통해 핵심 로직 깔끔하게 유지 |
연계 효과 | IoC/DI 기반에서 프록시 방식으로 AOP가 적용됨. 유연한 아키텍처 구성 가능 |