TIL - 20251210

juni·2025년 12월 10일

TIL

목록 보기
203/316

1210 Spring Framework 핵심 원리 복습: IoC/DI, AOP, PSA


✅ 1. IoC (Inversion of Control, 제어의 역전)와 DI (Dependency Injection, 의존성 주입)

  • IoC(제어의 역전)는 Spring 프레임워크의 가장 근본적인 설계 철학입니다.

  • 전통적인 방식: 개발자가 직접 객체를 생성(new MyService())하고, 의존성을 연결하며 프로그램의 흐름을 제어합니다. (제어권이 개발자에게 있음)

  • IoC 방식: 객체의 생성, 생명주기 관리, 의존성 연결 등 모든 제어권이 개발자로부터 프레임워크(Spring 컨테이너)로 넘어간(역전된) 것을 의미합니다.

  • DI(의존성 주입)IoC를 구현하는 구체적인 방법입니다.

    • 개념: 클래스가 필요로 하는 의존 객체를 내부에서 직접 생성하는 것이 아니라, 외부(Spring 컨테이너)에서 생성하여 주입(Injection)받는 방식입니다.
    • 핵심 원칙: 클래스는 구체적인 구현 클래스가 아닌, 추상적인 인터페이스에만 의존해야 합니다. (SOLID의 DIP)

➕ 의존성 주입의 장점과 방법

  • 장점:

    • 느슨한 결합 (Loose Coupling): 컴포넌트 간의 의존성이 줄어들어, 한 부분의 변경이 다른 부분에 미치는 영향을 최소화합니다.
    • 유연성 및 확장성: 의존하는 객체의 구현체를 쉽게 교체할 수 있습니다. (e.g., MySqlRepositoryPostgresRepository)
    • 테스트 용이성: 실제 객체 대신 가짜(Mock) 객체를 쉽게 주입하여 단위 테스트를 수행하기 매우 용이해집니다.
  • Spring의 DI 방법:

    • 생성자 주입 (Constructor Injection): 가장 권장되는 방식. final 키워드로 불변성을 보장하고, 의존성 누락을 방지하며, 순환 참조를 조기에 발견할 수 있습니다.
    • 필드 주입 / 수정자 주입: 테스트의 어려움, 불변성 위배 등의 단점으로 인해 현재는 거의 사용되지 않습니다.

✅ 2. Spring 컨테이너와 Bean

  • Spring 컨테이너 (IoC 컨테이너):

    • IoC와 DI를 실제로 구현한 Spring의 핵심 엔진입니다.
    • Bean의 생명주기를 관리하고, 의존성을 자동으로 주입해주는 역할을 합니다.
  • Bean:

    • Spring 컨테이너가 관리하는 객체를 의미합니다.
    • 개발자는 @Component 어노테이션(또는 이를 상속하는 @Service, @Repository, @Controller 등)을 클래스에 붙여, 해당 클래스의 객체를 Bean으로 등록해달라고 Spring에 요청합니다.
    • Spring은 시작 시점에 이 어노테이션들을 스캔하여 Bean 객체들을 생성하고 컨테이너에 보관했다가, @Autowired가 붙은 곳에 주입해줍니다.

✅ 3. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)

  • AOP는 OOP를 보완하는 프로그래밍 패러다임으로, 횡단 관심사(Cross-cutting Concerns)를 분리하여 코드의 모듈성을 높이는 기술입니다.

  • 횡단 관심사: 애플리케이션의 여러 비즈니스 로직(핵심 관심사)에 걸쳐 공통적으로 나타나는 부가 기능을 의미합니다. (e.g., 로깅, 트랜잭션, 보안, 예외 처리)

  • AOP의 해결책: 이러한 횡단 관심사를 "Aspect"라는 별도의 모듈로 분리하여, 핵심 비즈니스 로직에는 영향을 주지 않으면서 필요한 곳(Pointcut)에 동적으로 적용(Weaving)합니다.

  • Spring의 @Transactional: Spring AOP의 가장 대표적인 활용 사례입니다. 개발자는 비즈니스 로직에만 집중하고 @Transactional 어노테이션만 붙이면, Spring이 AOP를 통해 해당 메서드의 시작과 끝에 트랜잭션 시작/커밋/롤백이라는 부가 기능(Aspect)을 동적으로 적용해줍니다.


✅ 4. PSA (Portable Service Abstraction, 일관된 서비스 추상화)

  • PSA는 Spring 프레임워크가 제공하는 또 다른 중요한 가치로, 특정 기술에 종속되지 않는 일관된 방식의 API를 제공하는 설계 원칙입니다.

  • 문제점: 세상에는 다양한 기술 구현체들이 존재합니다. 예를 들어, 데이터베이스 트랜잭션을 관리하는 방식은 JPA, JDBC, Hibernate마다 모두 다릅니다. 만약 JPA를 사용하다가 JDBC로 기술을 변경하면, 트랜잭션과 관련된 모든 코드를 새로 작성해야 합니다.

  • Spring의 해결책 (PSA): Spring은 이러한 기술들의 세부 구현을 추상화하고, 개발자에게는 일관된 API를 제공합니다.

    • @Transactional: 개발자는 데이터 접근 기술이 JPA이든 JDBC이든 상관없이, @Transactional이라는 동일한 어노테이션을 사용하여 트랜잭션을 관리할 수 있습니다. 내부적으로는 Spring이 각 기술에 맞는 트랜잭션 관리자를 알아서 동작시켜 줍니다.
    • Spring Cache (@Cacheable): 캐시 기술이 Redis이든 Caffeine이든 상관없이, @Cacheable이라는 동일한 어노테이션으로 캐싱을 적용할 수 있습니다.
    • Spring AMQP (@RabbitListener): 메시지 큐 기술이 RabbitMQ이든 다른 AMQP 구현체이든 상관없이, 동일한 어노테이션으로 메시지를 소비할 수 있습니다.
  • 장점: PSA 덕분에 개발자는 특정 기술의 세부적인 API를 깊이 알지 못해도, Spring이 제공하는 일관된 방법으로 기술을 사용할 수 있습니다. 또한, 기반 기술이 변경되더라도 비즈니스 코드의 변경을 최소화할 수 있어 유연하고 확장성 있는 애플리케이션을 만들 수 있습니다.


📌 요약

  • IoC/DI는 객체 생성과 의존성 관리의 제어권을 Spring 컨테이너에 위임하여, 느슨한 결합테스트 용이성을 확보하는 Spring의 핵심 원리입니다.
  • AOP횡단 관심사(부가 기능)를 핵심 비즈니스 로직으로부터 분리하여, 코드의 중복을 제거하고 모듈성을 높이는 기술입니다.
  • PSA는 특정 기술의 구현细节을 추상화하고 일관된 API를 제공함으로써, 개발자가 기술 변화에 유연하게 대응하고 비즈니스 로직에 집중할 수 있도록 돕는 Spring의 중요한 설계 원칙입니다.

0개의 댓글