Spring (IoC, Bean, AOP)

Spring

🚀 이 주제를 선택한 이유 & 학습 목표

선택 배경: Spring 프레임 워크에 대해 놓친 부분 확인하기
학습 목표: Spring에 대해 다시 한번 복습하고, 정확한 구조 이해하기


📚 핵심 개념 및 원리

1. 주요 용어 정의

  • DIP (Dependency Inversion Principle)
    1. 상위 모듈은 하위 모듈에 의존 X
    2. 추상화는 세부 사항에 의존 X
  • SRP (Single Responsibility Principle)
    • 각 클래스는 하나의 책임만 가져야한다.
  • Aspect : 부가기능과 기능이 적용될 위치(Pointcut)을 합쳐 모듈화한 것
  • Join Point : 프로그램 실행 중 특정시점, Spring AOP에서는 항상 메서드 실행을 뜻함
  • Advice : Aspect가 특정 Join Point에서 수행하는 실제 비즈니스 로직
  • Target : Advice를 받는 핵심 비즈니스 로직을 수행하는 객체
  • Weaving : Aspect를 다른 애플리케이션 타입이나 객체에 연결하여 Advice를 적용된 객체를 만드는 과정
  • CGLIB : 클래스 상속과 바이트 코드 조작으로 프록시 생성해주는 라이브러리

2. 핵심 원리/동작 방식

  • IoC (Inversion of Control)

  • 객체의 생성, 생명주기 관리 등 제어권이 개발자가 아닌 프레임워크에게 넘어가는 것

    • Spring IoC 컨테이너

      • Bean을 관리하는 핵심 엔진

      • 객체 생성 : 설정 메타 데이터 기반 Bean 객체 인스턴스화

      • DI (Dependency Injection) : Bean 객체 간의 의존 관계 자동 연결

        • @Autowired : DI 자동 어노테이션
      • 생명주기 관리

      • XML, 어노테이션 등 설정 기반 Bean 관리

      • BeanFactory VS ApplicationContext

    1. BeanFactory : IOC의 기본 형태, Bean 생성과 DI 기능 제공
    2. ApplicationContext : BeanFactory + 트랜잭션 관리, 이벤트 메커니증 등 추가 기능
  • Spring Bean

  • Spring IoC 컨테이너에 의해 생성되고, 관리되고, 의존성이 주입되는 객체

  • Bean 스코프 : 컨테이너가 Bean 인스턴스를 생성하고 관리하는 방식 결정

    • singleton (default) : Spring IoC 컨테이너 내에서 단 하나의 인스턴스만 생성
    • prototype : Bean을 요청할 때마다 새로운 인스턴스 생성
    • request : 각 HTTP 요청마다 새로운 인스턴스 생성
    • session : 각 HTTP 세션마다 새로운 인스턴스 생성
    • application : ServletContext 생명주기와 동일하게 하나의 인스턴스 생성
  • AOP (Aspect-Oriented Programming)

  • OOP 과정에서 공통 부가 기능들을 핵심 비즈니스 로직으로부터 분리하여 별도의 모듈(Aspect)로 관리

  • Spring IoC를 보완

  • 런타임에 프록시 객체 (기존 객체 + Aspect) 를 사용 -> JDK 동적 프록시 또는 CGLIB 라이브러리를 통해 생성

  • 프록시 기반으로 메서드 실행 시점에만 부가 기능 적용

3. 관련 예시 또는 시나리오

  • new 객체 생성 VS 생성자 주입
  1. new 사용
public class OrderService {
    private PaymentService paymentService;

    public OrderService() {
        this.paymentService = new RealPaymentService(); // OrderService가 직접 RealPaymentService 객체를 생성
    }

    public void processOrder() {
        // paymentService 사용
    }
}
  1. OrderService 클래스가 RealPaymentService라는 객체를 직접 생성하고 관리할 책임을 가짐
  2. PaymentService의 다른 구현체를 사용하려면 OrderService를 수정해야한다.

  1. 생성자 주입
@Service // OrderService도 Spring Bean으로 등록
public class OrderService {
    private final PaymentService paymentService; // 인터페이스에 의존, final로 불변성 확보 가능

    @Autowired // Spring 4.3 이후 생성자가 하나면 생략 가능[4][12]
    public OrderService(PaymentService paymentService) { // 생성자를 통해 PaymentService 타입의 Bean을 주입받음
        this.paymentService = paymentService;
    }

    public void processOrder() {
        // paymentService 사용
    }
}

// PaymentService 인터페이스
public interface PaymentService { /* ... */ }

@Component // RealPaymentService를 Spring Bean으로 등록
public class RealPaymentService implements PaymentService { /* ... */ }
  1. 객체 생성의 책임은 Spring IoC 컨테이너
  2. 구현체가 아닌 인터페이스에 의존

결국 인터페이스에 의존하는 것은 동일하지 않나 ?

  • DI의 목적은 결국 의존하는 클래스에서 구현체에 대한 의존을 끊는 것.
@Service // D 클래스도 Spring Bean
public class D {
    private final A paymentProcessor; // A 인터페이스에만 의존

    @Autowired
    public D(A paymentProcessor) { // 외부에서 A 인터페이스의 구현체를 주입받음
        this.paymentProcessor = paymentProcessor;
    }

    public void processPayment() {
        paymentProcessor.pay();
    }
}

// --- Spring 설정 부분 ---
// 방법 1: B를 기본 구현체로 사용
@Component
@Primary // B를 A 타입의 기본 Bean으로 지정
public class B implements A {
    @Override
    public void pay() {
        System.out.println("B의 방식으로 결제");
    }
}

@Component
public class C implements A {
    @Override
    public void pay() {
        System.out.println("C의 방식으로 결제");
    }
}
  1. 동일 인터페이스의 다른 구현체로 교체 용이 -> 테스트 코드 작성 시 가짜 구현체 또한 사용가능
  2. 의존한 클래스가 아닌 구현체만을 변경하여 수정 가능

=> 객체의 응집도 향상, 결합도 낮추어 객체의 단일 책임 강화


🤔 나의 이해와 생각 정리 (회고)

핵심 요약: Spring 프레임워크의 모든 기능들의 지향점은 JAVA의 객체 지향성을 극대화하여 개발 효율성 향상이 목적으로 보인다.

새롭게 깨달은 점: 생각보다 용어나 개념에 대해서 정확히 정의내리지 못한 부분이 많았다. 안다고 생각했던 부분에 대해 미흡한 점을 많이 찾을 수 있었다.

더 궁금해진 점 / 의문점: 프레임워크 제작은 어떤식으로 이루어지는 것인가?


📖 더 학습할 내용 및 참고 자료

추가 학습 희망 분야: Spring Security, Filter, Intercept


✨ 마무리하며

앞으로도 모호했던 부분에 대한 지속적인 학습이 필요하다 느꼈다. 새로운 기술 이전에 기존의 사용하던 것들에 대한 지식에 대한 검증이 필요해 보인다.

'Study > CS' 카테고리의 다른 글

정렬 3편 (힙(Heap)과 힙 정렬)  (2) 2025.07.29
정렬 2편 (분할 정복: 병합 정렬, 퀵 정렬)  (2) 2025.07.29
정렬 1편 (버블 정렬, 선택 정렬, 삽입 정렬)  (3) 2025.07.29
String과 StringBuilder  (0) 2025.06.27
JVM  (1) 2025.05.26