스프링 삼각형과 설정 정보
- 7.1 IoC/DI — 제어의 역전과 의존성 주입
- 7.2 AOP — 관점 지향 프로그래밍
- 7.3 PSA — 일관성 있는 서비스 추상화
스프링은 마법이 아니야. 1장부터 6장까지 쌓아온 모든 것 — 메모리 구조, 캡상추다, SOLID, 디자인 패턴 — 이 전부 여기로 수렴해.
저자가 말하는 스프링 삼각형의 첫 번째 꼭짓점은 IoC/DI야. 예전엔 개발자가 new MySQLOrderRepository()로 직접 객체를 만들고 의존 관계를 설정했어. 제어권이 개발자한테 있었지. 스프링에서는 OrderService가 자기가 쓸 OrderRepository를 직접 만들지 않아. 생성자에 인터페이스 타입으로 선언만 해놓으면, 스프링 컨테이너가 알아서 구현체를 찾아 넣어줘. 제어권이 외부로 넘어간 거야 — 이게 "역전"의 의미지. 6장에서 Sorter에게 SortStrategy를 외부에서 주입하던 전략 패턴 기억나지? 그거랑 정확히 같은 원리인데, 스프링은 컨테이너가 자동으로 해준다는 점만 다를 뿐이야. 결국 IoC/DI는 DIP(의존 역전 원칙) 의 프레임워크 레벨 구현이야.
두 번째 꼭짓점은 AOP야. 비즈니스 로직이 repository.save(order) 한 줄인데, 로깅, 보안, 트랜잭션, 성능 측정 코드가 앞뒤로 덕지덕지 붙어 있는 거 봤잖아. 이런 횡단 관심사가 수십 개 서비스 메서드에 복붙되면 유지보수가 지옥이 돼. AOP는 이걸 비즈니스 코드에서 떼어내서 별도 모듈(Aspect)로 분리해. 비즈니스 코드는 핵심 로직만 갖고 있고, 로깅이든 트랜잭션이든 Aspect가 알아서 끼워넣어. 어떻게? 6장에서 배운 프록시 패턴으로. 스프링이 프록시 객체를 만들어서, 호출이 프록시를 거치면서 부가 기능이 처리되고 나서 실제 메서드가 호출되는 구조야. 개발자는 프록시의 존재를 모르고 그냥 코드를 짜면 돼.
세 번째 꼭짓점은 PSA야. JDBC, JPA, MyBatis — 다 API가 다른데 하는 일은 같잖아. 스프링은 이런 다양한 기술 위에 일관된 추상화 계층을 씌워. @Transactional 하나면 뒤에서 JDBC를 쓰든 JPA를 쓰든 개발자 코드는 똑같아. 기술 스택이 바뀌어도 비즈니스 코드를 안 고쳐도 되는 거지. 이건 DIP + OCP + 어댑터 패턴의 결합이야.
결국 스프링의 세 기둥 전부가 SOLID에서 나와. IoC/DI는 DIP, AOP는 SRP와 OCP, PSA는 DIP와 OCP. SOLID를 이해하면 스프링이 왜 그렇게 동작하는지가 보이고, 모르면 그냥 어노테이션 찍는 기계가 되는 거야.
정리
7장 읽고 기억할 거 세 가지:
- IoC/DI는 "내가 만들지 않고 받는다"는 원리다. 객체 생성과 의존 관계 설정을 스프링 컨테이너가 대신한다. DIP와 전략 패턴의 프레임워크 레벨 구현
- AOP는 횡단 관심사를 비즈니스 로직에서 분리하는 것이다. 프록시 패턴 기반으로 로깅, 트랜잭션, 보안 같은 코드를 비즈니스 코드 수정 없이 적용한다
- PSA는 기술 교체 비용을 최소화하는 추상화 계층이다. 구현 기술이 바뀌어도 개발자 코드는 동일하게 유지된다. 어댑터 패턴 + DIP의 결합