Design pattern 2. Proxy Pattern

김미숙's avatar
Jul 22, 2025
Design pattern 2. Proxy Pattern

✅ 프록시(Proxy)란?

  • 클라이언트(Client)와 서버(Server) 사이에서 요청이나 응답을 대신 처리해주는 중간 대리자
  • 클라이언트가 직접 서버에 접근하지 않고, 프록시를 거쳐서 우회하는 방식
 

💡 실생활 예시

회사 네트워크에서 특정 사이트 접속 시 → 프록시 서버가 대신 요청하고 → 결과를 직원 컴퓨터에 전달
 

📦 프록시의 종류와 목적

종류
설명
주요 용도
웹 프록시
클라이언트 요청을 대신 웹 서버에 전달
캐시, IP 우회, 차단 우회
리버스 프록시
클라이언트 입장에서는 서버처럼 보임 (요청을 여러 내부 서버로 라우팅)
로드 밸런싱, 보안
캐시 프록시
요청 결과를 저장하고, 같은 요청 시 재사용
속도 향상
보안 프록시
악성 요청 차단, 방화벽 역할
보안 필터링
애플리케이션 프록시
특정 객체나 기능 접근을 대신 수행
소프트웨어 설계 패턴 (ex: Proxy Pattern)

🧑‍💻 예: 소프트웨어 설계에서의 프록시 패턴

public interface Image { void display(); } public class RealImage implements Image { public void display() { System.out.println("실제 이미지 표시"); } } public class ProxyImage implements Image { private RealImage realImage; public void display() { if (realImage == null) { realImage = new RealImage(); // 필요할 때만 생성 (지연 로딩) } realImage.display(); } }
👉 클라이언트는 ProxyImage를 통해 RealImage에 간접 접근합니다.
(대표적: 지연 로딩, 접근 제어, 로깅 등에 활용)

정리 문장

프록시란, 원래 대상에 대한 접근을 대신하거나 중간에서 처리해주는 대리자이며,
네트워크/보안/설계패턴 등 다양한 분야에서 활용됩니다.
 

실습

DoormanProxy

  • composition
  • Proxy가 여러 개가 되면 Doorman을 추상화시켜야 DIP (의존 역전 원칙) 를 지킬 수 있다
package ex02; /* * DoormanProxy의 역할 * "안녕" 인사 후 동물을 쫒아낸다 - 새로운 코드 확장 * Doorman이 "안녕" 인사하는 건 OCP 위배 * */ // extends에 문제는 없으나 의미상 안맞음 public class DoormanProxy { private Doorman doorman; // has // 의존성 주입 public DoormanProxy(Doorman doorman) { this.doorman = doorman; } public void 쫓아내(Animal animal) { System.out.println("안녕"); doorman.쫓아내(animal); } }

App

package ex02; public class App { public static void main(String[] args) { // 1. init (객체 초기화) Mouse m1 = new Mouse(); Doorman d1 = new Doorman(); Cat c1 = new Cat(); DoormanProxy dp = new DoormanProxy(d1); // 2. run dp.쫓아내(m1); dp.쫓아내(c1); } }
notion image
 

 

✅ 프로그래밍에서 프록시가 쓰이는 대표 사례

분류
사례
설명
🔒 보안 제어
접근 제한 (Access Control)
예: 관리자만 호출 가능하도록 제어
🧭 지연 로딩
Lazy Initialization
실제 객체가 필요할 때까지 생성을 미룸
🧾 로깅/모니터링
요청 시 로그 기록
메서드 호출 전에 로그를 출력하거나 분석 도구 연결
🧪 테스트/모킹
테스트용 가짜 객체 대체
실제 객체 없이 테스트용 프록시로 대체
🌀 캐싱
이전 결과 재사용
동일 요청 시 저장된 결과 반환하여 성능 향상
🔁 원격 호출 (RPC)
원격 서비스 호출 프록시
실제 서버와의 통신을 프록시가 중개 (ex: gRPC, RMI)
🧩 AOP (Aspect-Oriented Programming)
Spring에서의 @Transactional, @Loggable
프록시 객체가 핵심 로직 전후에 부가 기능 삽입
🌐 HTTP 클라이언트 프록시
Retrofit, Feign 등에서 인터페이스를 통한 API 호출
선언형 HTTP 호출을 실제 프록시가 처리

💡 예시: Spring AOP 프록시

@LogExecutionTime public String getData() { // 핵심 비즈니스 로직 }
  • @LogExecutionTime은 실제 getData() 메서드를 감싸는 프록시 객체가 생성되어
  • 실행 전/후 시간 측정을 자동으로 삽입합니다.

💡 예시: Lazy Loading 프록시

ORM 프레임워크 (ex: Hibernate)에서는 @OneToMany(fetch = FetchType.LAZY) 설정 시
프록시 객체를 반환하고,
→ 실제 데이터는 접근할 때 DB에서 조회함.

🧠 핵심 요약

프록시는 '실제 객체에 대한 대리자'로서, 접근 제어, 부가기능 삽입, 성능 최적화 등에 활용됩니다.
 

Forward Proxy와 Reverse Proxy

Forward Proxy (정방향 프록시)

🔍 개념
클라이언트(사용자)**가 프록시 서버를 통해 외부 서버에 간접적으로 접근하는 방식
🧭 동작 흐름
  1. 클라이언트가 요청을 프록시에 보냄
  1. 프록시가 외부 서버에 대신 요청
  1. 응답을 프록시가 받아 클라이언트에 전달
🛠️ 사용 목적
  • 사용자의 IP 주소 숨김 (익명성 보장)
  • 방화벽 우회 (접근 제한 회피)
  • 인터넷 사용 제어 (예: 학교/회사에서 특정 사이트 차단)
  • 캐시 기능으로 응답 속도 향상 및 트래픽 절감
📌 사용 예시
  • VPN, Tor 네트워크
  • 회사에서 유해 사이트 접속 제한
  • IP 우회를 위한 개인 프록시 서버

Reverse Proxy (역방향 프록시)

🔍 개념
서버 측에 위치하여, 클라이언트는 프록시에게 요청을 보내고 프록시가 적절한 내부 서버에 요청을 전달하는 방식
🧭 동작 흐름
  1. 클라이언트는 서버 주소로 요청을 보냄 (사실은 프록시)
  1. 리버스 프록시가 요청을 받고
  1. 내부 서버 중 하나에 요청 전달
  1. 내부 서버 응답을 받아 클라이언트에 전달
🛠️ 사용 목적
  • 로드 밸런싱 (여러 서버로 트래픽 분산)
  • 보안 (내부 서버 IP, 구조 감춤)
  • SSL 처리 (HTTPS 통신 처리)
  • 캐시 (정적 리소스 응답 속도 향상)
  • 웹 방화벽 역할 (악의적인 요청 필터링)
📌 사용 예시
  • Nginx, Apache HTTP Server의 리버스 프록시 설정
  • Cloudflare 같은 CDN 서비스
  • AWS Load Balancer
  • Spring Boot 앱 앞단에 Nginx로 프록시 설정

🧩 Forward Proxy vs Reverse Proxy 정리표

항목
Forward Proxy
Reverse Proxy
위치
클라이언트 앞단
서버 앞단
누굴 대신?
클라이언트(사용자)
서버(서비스 제공자)
목적
사용자 보호, 검열 우회
서버 보호, 분산 처리
사용자 시야
외부 서버가 보임
내부 서버가 숨겨짐
대표 기능
접근 통제, IP 우회
로드 밸런싱, SSL, 보안
대표 예
VPN, Tor, 회사 프록시
Nginx, Cloudflare, AWS LB

💡 핵심 비유로 기억하기

  • Forward Proxy = "내가 직접 요청 안 하고 누군가를 통해 우회해서 요청"
  • Reverse Proxy = "누군가가 내 앞에서 요청을 받아서 내부적으로 적절히 처리 후 결과만 보여줌"
 
Share article

parangdajavous