백엔드 - 스프링의 3요소

스프링의 3요소란?

Spring Framework의 주축이 되는 3가지 개념을 말한다.

  • IoC/DI (제어의 역전 / 의존성 주입)
  • AOP(Aspect Oriented Programming)
  • PSA(Portable Service Abstraction

1-1. IoC — 제어의 역전

핵심 객체 생성의 주도권이 개발자 → 스프링으로 넘어가는 것

제어의 역전은 다른 객체를 직접 생성하거나 제어하는 것이 아니라 외부에서 관리하는 객체를 가져와 사용하는 것을 말한다. 클래스 B 객체를 직접 생성하는 것이 아니므로, 어딘가에서 받아와서 사용하고 있다고 추측해볼 수 있다. 이처럼 제어의 역전을 적용하면 객체를 외부에서 관리하게 되고, 실제로 사용할 때에는 외부에서 제공해주는 객체를 받아오게 된다.

스프링에서는 제어의 역전 개념을 중요한 컨셉으로 삼고 있으며, 여기서 외부(= 객체를 관리하는 주체)를 “스프링 컨테이너”라고 한다.

```plain text // 기존 — 개발자가 직접 new OrderService order = new OrderService(new FixDiscountPolicy());

// IoC — 선언만 하면 스프링 컨테이너가 알아서 만들어줌 @Service public class OrderService { … }



핵심: `new`를 개발자가 안 써도 됨. 스프링 컨테이너가 대신 객체를 만들고 관리.


**Q. "제어가 역전된다"는 게 뭔데?**


기존은 개발자 코드가 직접 `new` 해서 객체를 만듦 → 개발자가 주도권.IoC는 `@Service` 달아놓고 기다리면 스프링이 알아서 만들어서 줌 → 스프링이 주도권."누가 만드냐"의 주도권이 바뀐 것 = 역전.


**Q. 결국 코드 어딘가는 고쳐야 하잖아. 기존이랑 뭐가 달라?**


고치는 건 맞음. 근데 **어디를** 고치냐가 다름.기존은 Fix가 OrderService, CartService... 여러 파일에 흩어져 있어서 다 찾아서 고쳐야 함.IoC는 Fix가 AppConfig 딱 한 곳에만 있어서 거기만 고치면 끝.


## **1-2. DI — 의존성 주입**


**핵심** 필요한 객체를 밖에서 파라미터로 넣어주는 것


스프링에서는 객체들을 관리하기 위해 제어의 역전을 사용한다. 그리고 **제어의 역전을 구현하기 위해 사용하는 방법이 DI**다.


의존성 = 없으면 동작 못 하는 관계. OrderService는 DiscountPolicy 없으면 동작 못 함.


```plain text
// 나쁜 방식 — Fix가 안에 박혀있음
class OrderService {
    DiscountPolicy dp = new FixDiscountPolicy(); // 바꾸려면 이 파일 직접 고쳐야 함
}

// DI 방식 — 밖에서 넣어줌
class OrderService {
    DiscountPolicy dp;

    public OrderService(DiscountPolicy dp) {
        this.dp = dp;
    }
}

@Service
@RequiredArgsConstructor
public class OrderService {
    private final DiscountPolicy dp;  // 스프링이 알아서 꽂아줌
}

OrderService 코드는 하나도 안 건드리고, 파라미터만 바꾸면 됨.

final + 생성자 주입 조합 권장: 한 번 주입되면 못 바꾸니까 안전하고, 반드시 주입받아야 한다는 걸 강제.

2. PSA — 서비스 추상화

핵심 기술이 바뀌어도 내 코드는 안 바꿔도 됨

스프링이 제공하는 다양한 기술(JPA, MyBatis, JDBC 등)을 추상화해 개발자가 일관된 방식으로 쓸 수 있게 해줌. 어떤 DB 기술을 사용하든 일관된 방식으로 데이터베이스에 접근하도록 인터페이스를 지원함.

```plain text // DB 기술이 바뀌어도 코드는 그대로 repository.save(객체); // JDBC든 JPA든 MyBatis든 똑같이 씀



DIP 원칙을 스프링이 기술(DB, 트랜잭션 등)에 직접 적용한 것. DB 깊이 배우면 더 잘 이해됨.


## **3. AOP — 관점 지향 프로그래밍**


**핵심** 공통 기능(로그, 보안, 트랜잭션)을 따로 빼서 한 곳에서 관리


| **종단 (세로)**        | **횡단 (가로)**          |
| ------------------ | -------------------- |
| 핵심 로직 (주문, 결제, 배송) | 공통 기능 (로그, 보안, 트랜잭션) |
| 각 기능이 독립적으로 흐름     | 모든 기능을 가로로 횡단하며 적용   |


```plain text
// AOP 없으면
public void 주문() { 로그(); 보안(); /* 주문 로직 */ }
public void 결제() { 로그(); 보안(); /* 결제 로직 */ }

// AOP 있으면
@Aspect
public class CommonAspect { 로그(); 보안(); }

public void 주문() { /* 주문 로직만 */ }
public void 결제() { /* 결제 로직만 */ }