스프링 DI

키요·2025년 9월 1일

공부

목록 보기
16/32

스프링 DI를 '스마트 컴퓨터 공장' 비유로 정복해봤는데요

스프링 프레임워크를 처음 접하면 수많은 어노테이션과 개념들이 마법처럼 느껴집니다.

하지만 그 중심에는 '객체를 부품처럼 조립하여 완성품을 만드는' 매우 체계적인 철학이 담겨 있습니다.

이 글에서는 스프링의 핵심 원리를 '최첨단 스마트 컴퓨터 조립 공장'에 비유하여 설명하고자 합니다.

1. 공장의 심장부: 자동화 창고와 조립 라인 (IoC 컨테이너)

우리 스마트 공장의 핵심은 모든 부품을 자동으로 생성하고 보관하며, 필요할 때 정확히 찾아 연결해주는 자동화 창고 및 조립 라인입니다. 이것이 바로 스프링 IoC 컨테이너입니다. 개발자는 더 이상 부품을 직접 만들거나 찾아다닐 필요가 없습니다.

2. 공장의 3계층 구조와 부품 설계도

현대적인 공장은 역할에 따라 명확하게 구역이 나뉩니다. 스프링 애플리케이션 역시 3계층 아키텍처(3-Tier Architecture)로 역할을 분담하며, 각 클래스에 특정 어노테이션을 붙여 설계도로 등록합니다.

1계층: 표현 계층 (Presentation Layer)

  • @Controller (고객 주문 처리 및 출하팀): 외부(클라이언트)의 주문(웹 요청)을 접수하고 완성품(응답)을 내보내는 역할을 전담합니다.

2계층: 비즈니스 계층 (Business Layer)

  • @Service (메인 조립 라인): CPU, RAM 등 여러 부품을 조합하여 컴퓨터의 핵심 기능(비즈니스 로직)을 완성하는 가장 복잡하고 중요한 작업을 수행합니다.

3계층: 데이터 접근 계층 (Persistence Layer)

  • @Repository (부품 창고 관리팀 - DAO): 데이터베이스라는 거대한 창고에서 원자재(데이터)를 가져오거나 저장하는 역할을 합니다.

데이터를 옮기는 표준 규격: DTO, VO, DAO

공장에서 부품과 정보가 오갈 때는 정해진 규격의 상자나 서류를 사용합니다.

  • DTO (Data Transfer Object): '작업 지시서' 또는 '부품 운송 상자'와 같습니다. 계층 간에 데이터를 전달할 때 사용하는 전용 객체입니다.
  • VO (Value Object): '변경 불가능한 부품 스펙 라벨'과 같습니다. 데이터 자체가 고유한 값을 가지며, 일단 만들어지면 절대 바뀌지 않는 객체입니다.
  • DAO (Data Access Object): '창고 관리 시스템의 사용 설명서(인터페이스)'입니다. @Repository 어노테이션이 붙은 클래스는 이 DAO 설계를 실제로 구현한 구현체입니다.

3. 궁극의 자동화: 부품 조립 (@Autowired - 의존성 주입)

이 공장의 가장 위대한 점은 자동 조립입니다. 메인보드 설계도(OrderService)에 "CPU 소켓에는 CPU 부품이 필요함"이라고 적어두기만 하면 됩니다.

@Service // 메인 조립 라인 설계도
public class OrderService {

    // "이 자리에는 'PaymentService' 규격에 맞는 부품이 필요합니다. 자동으로 조립해주세요."
    @Autowired
    private PaymentService paymentService;

    public void assembleComputer(OrderRequestDTO orderDTO) { // DTO로 작업 지시를 받음
        // 자동 조립된 paymentService 부품의 전원을 켠다.
        paymentService.pay(orderDTO);
    }
}

조립 라인은 OrderService라는 제품을 만들다가 @Autowired를 발견하면, 즉시 자동화 창고에서 PaymentService 규격에 맞는 부품을 찾아와 정확한 위치에 "딸깍"하고 끼워줍니다.

왜 직접 조립하지 않을까? (new 방식 vs DI 방식)

여기서 한 가지 의문이 생길 수 있습니다. "그냥 클래스 안에서 new로 직접 부품을 만들면 안 되나?" 물론 가능하지만, 스마트 공장은 그런 비효율적인 방식을 사용하지 않습니다.

  • 직접 조립 (new 방식)의 문제점
    메인보드 설계자가 CPU를 직접 만들어서 보드에 영구적으로 납땜해버리는 것과 같습니다.

    public class OrderService {
        // CPU(KakaoPayService)를 직접 만들어 납땜해버렸다!
        private PaymentService paymentService = new KakaoPayService();
    }
    • 유연성 부족: CPU를 업그레이드하려면 메인보드 전체를 버리고 새로 만들어야 합니다. 즉, 결제 방식을 바꾸고 싶을 때마다 OrderService.java 파일을 직접 열어서 코드를 수정해야 합니다.
    • 테스트 어려움: 메인보드 성능 테스트를 위해 값비싼 실제 CPU를 항상 사용해야만 합니다. 간단한 테스트용 부품을 끼워볼 수가 없습니다. 즉, 원본 코드를 변경하지 않고는 테스트용 가짜 객체를 투입하기가 매우 어렵습니다.
  • 스프링 자동 조립 (DI 방식)의 장점
    스마트 공장은 표준화된 CPU 소켓을 사용합니다.

    • 유연성과 확장성: 오늘은 인텔 CPU를, 내일은 AMD CPU를 자유롭게 교체할 수 있습니다. OrderServicePaymentService라는 표준 소켓만 알면 되므로, 자바 코드를 수정하지 않고도 외부 설정(@Bean 등)을 통해 KakaoPayServiceNaverPayService로 쉽게 교체할 수 있습니다.
    • 중앙 관리: 어떤 CPU를 사용할지는 메인보드 설계자가 아닌, 공장의 중앙 관제실(설정 파일)에서 결정합니다. 이처럼 의존 관계가 코드 밖에서 명확하게 관리되므로 전체 시스템을 파악하고 변경하기가 훨씬 쉽습니다.

이것이 바로 의존성 주입(DI)의 진정한 힘입니다.

4. 반복 작업 해결사: 3D 프린터 (Lombok)

컴퓨터를 조립할 때마다 나사, 볼트 같은 수많은 표준 부품이 필요합니다. Lombok은 공장의 고성능 3D 프린터와 같습니다.

@Getter
@Setter
public class ComputerPartsDTO { // DTO 클래스에 주로 사용
    private String name;
}

@Getter, @Setter라고 지정만 해주면, 컴파일 시점에 3D 프린터가 해당 부품의 Getter, Setter 메서드를 자동으로 "찍어냅니다". 덕분에 엔지니어(개발자)는 사소한 작업에서 해방되어 핵심 부품 설계에만 집중할 수 있습니다.

5. 결론: 왜 이 공장이 뛰어난가?

스프링이라는 스마트 공장은 단순히 편리하기만 한 것이 아니라, 훌륭한 객체지향 설계 원칙을 자연스럽게 따르도록 유도합니다.

  • 추상화/다형성: "CPU 소켓"이라는 표준 규격(인터페이스)만 맞으면 어떤 회사의 CPU든 장착할 수 있습니다.
  • 캡슐화: 메인보드 조립팀은 CPU의 복잡한 내부 회로를 알 필요 없이, 정해진 핀에 연결만 하면 됩니다.

결론적으로 스프링은 개발자가 잘 설계된 독립적인 부품(Bean)들을 만드는 데 집중하게 하고, 조립이라는 복잡하고 실수하기 쉬운 작업은 프레임워크가 책임지는 고도로 발달한 생산 방식입니다. 이 원리를 이해하면 스프링의 진정한 강력함을 경험할 수 있습니다.

profile
운도 실력

0개의 댓글