1. Proxy 패턴이란?

Proxy 패턴은 어떤 객체에 대한 접근을 제어하거나, 그 객체를 대신하여 추가 작업을 수행할 수 있도록 중간 대리 객체(Proxy)를 두는 디자인 패턴입니다.

사용 목적

  • 실제 객체의 접근 제어
  • 객체 생성 비용이 클 때 지연 로딩
  • 부가 기능 부여 (로그, 인증, 캐시 등)

적용 사례

  • 데이터베이스 연결 풀 관리
  • 보안 검사/권한 제어
  • Spring의 AOP 기반 기능들 (@Transactional, @Async, @Cacheable 등)

2. 구조와 동작 원리

기본 구조

클라이언트 → Proxy → 실제 객체(RealSubject)

예시 클래스 구조

public interface Service {
    void doSomething();
}

public class RealService implements Service {
    public void doSomething() {
        System.out.println("Real service logic");
    }
}

public class LoggingProxy implements Service {
    private final Service target;

    public LoggingProxy(Service target) {
        this.target = target;
    }

    public void doSomething() {
        System.out.println("[Log] Before");
        target.doSomething();
        System.out.println("[Log] After");
    }
}

3. Spring에서 Proxy 패턴 적용 예시

Spring에서는 Proxy 기반 AOP 구현이 핵심 메커니즘입니다. 실제 객체 앞에 프록시 객체를 두어 횡단 관심사를 처리합니다.

대표 예시: @Transactional

@Service
public class OrderService {
    @Transactional
    public void placeOrder() {
        // 트랜잭션 처리 전/후 프록시가 개입
    }
}

이때 Spring은 OrderService의 프록시를 생성하여, 메서드 실행 전후에 트랜잭션을 시작하고 커밋 또는 롤백합니다.


4. 장단점

장점단점

장점 단점
원래 객체 수정 없이 부가 기능 삽입 가능 클래스 수 증가, 구조 복잡도 증가
접근 제어, 보안, 로깅 등 분리 가능 성능 오버헤드 가능성 있음
AOP, 리모팅, 캐시 등 확장 기능에 유리 디버깅 난이도 상승

5. 실무 적용 팁

  • 횡단 관심사(Cross-cutting concern) 가 많다면 Proxy 또는 AOP 적용 고려
  • 무분별한 프록시 체인 생성은 성능 저하 원인이 될 수 있음
  • Spring에서는 @Aspect, @Around, @Before 등을 통해 선언형 AOP를 쉽게 구현 가능
@Aspect
@Component
public class LogAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeLog() {
        System.out.println("[LOG] 메서드 실행 전");
    }
}

6. 실무에서 Proxy 패턴은 어디까지 쓰는가?

Spring에서 Proxy 패턴(AOP 포함)은 대부분 횡단 관심사(부가 기능) 를 분리해 처리하는 용도로 사용됩니다. 다음과 같은 기능들이 대표적입니다:

활용 예시 설명
@Transactional 트랜잭션 시작/커밋/롤백을 자동으로 처리
@Cacheable 메서드 결과 캐싱 및 캐시 무효화 관리
@Async 비동기 실행 처리
@PreAuthorize 메서드 실행 전 권한 검사
@Before, @After 메서드 실행 전후 로깅 또는 감사 처리

이처럼 대부분의 AOP 기반 기능은 실제 비즈니스 로직은 건드리지 않고, 그 앞뒤에서 감싸는 형태로 구현됩니다.

Proxy 패턴의 전형적인 실전 활용입니다.

💡 핵심 로직(예: 주문 생성, 결제 처리 등)은 여전히 Controller → Service → Repository 구조 내에서 구현되며, 프록시는 이를 감시하거나 감싸는 역할만 수행합니다.

Proxy를 통해 로직 자체를 변경하거나 처리하는 일은 매우 드물며, 오히려 설계를 복잡하게 만들고 유지보수를 어렵게 만들 수 있습니다. 따라서 프록시는 부가 기능 전용으로 활용하고, 핵심 비즈니스는 명확히 계층 구조 안에서 처리하는 것이 일반적인 설계 방향입니다.


7. 마무리 요약

  • Proxy 패턴은 실제 객체에 대한 접근을 제어하거나, 실행 전후로 로직을 삽입할 수 있는 구조입니다.
  • Spring AOP는 이러한 Proxy 패턴을 기반으로 작동하며, 트랜잭션, 보안, 로깅 등의 핵심 기능을 지원합니다.
  • 코드 분리와 유지보수성을 위해, 필요한 경우에만 명확하게 프록시를 도입해야 합니다.
 

+ Recent posts