실제 객체를 대신해 서서 접근을 제어하는 패턴.
interface Image { void display(); }
class RealImage implements Image {
RealImage(String file) { loadFromDisk(file); } // 생성이 비싸다
public void display() { ... }
}
class ImageProxy implements Image {
private RealImage real;
private final String file;
public void display() {
if (real == null) real = new RealImage(file); // 실제로 필요할 때 만든다
real.display();
}
}
종류
- 가상 프록시 — 생성이 비싼 객체를 지연 생성한다 (ORM 의 지연 로딩)
- 보호 프록시 — 권한을 확인하고 통과시킨다
- 원격 프록시 — 네트워크 너머 객체를 로컬 객체처럼 보이게 한다 (RPC 스텁)
- 캐싱 프록시 — 결과를 저장했다 재사용한다
- 스마트 참조 — 참조 횟수를 세거나 부가 동작을 한다
프레임워크가 이 위에 서 있다
-
트랜잭션·캐시·보안 애노테이션 → 프록시가 메서드를 가로채 부가 동작을 넣는다
-
ORM 의 지연 로딩 → 프록시 객체를 넣어 두고 실제 접근 시 조회한다
-
원격 호출 스텁 → 로컬 호출처럼 보이는 프록시
-
"애노테이션 하나로 동작이 바뀌는" 마법의 정체가 대개 프록시다
그래서 따라오는 제약
프록시는 '바깥에서 들어오는 호출' 만 가로챈다
- 같은 객체 안에서 자기 메서드를 부르면 프록시를 거치지 않는다
- 애노테이션이 조용히 무시된다
또한 final 클래스·final 메서드·private 메서드는 감쌀 수 없다
Facade — 복잡한 것을 단순한 창구로
// 하위 시스템 여럿을 감춘다
class VideoConverter {
public File convert(String file, String format) {
VideoFile v = new VideoFile(file);
Codec src = CodecFactory.extract(v);
Codec dst = format.equals("mp4") ? new Mpeg4Codec() : new OggCodec();
return BitrateReader.convert(v, src, dst);
}
}
-
Proxy — 같은 인터페이스로 하나를 감싼다 — 접근 제어
-
Facade — 새 인터페이스로 여러 개를 감춘다 — 단순화
-
Adapter — 다른 인터페이스로 변환한다 — 호환
-
셋 다 "감싼다" 이지만 목적이 각각 다르다
면접 함정
- ❌ "Proxy는 성능 최적화용" → 지연 로딩은 한 종류일 뿐이다. 접근 제어가 본질이다.
- ❌ "Facade를 두면 하위 시스템을 못 쓴다" → 감추는 것이지 막는 것이 아니다. 필요하면 직접 쓸 수 있다.
동적 프록시 — 런타임에 만든다
// 인터페이스만 있으면 구현을 런타임에 생성할 수 있다
Object proxy = Proxy.newProxyInstance(
loader, new Class[]{Service.class},
(p, method, args) -> {
log.info("호출: " + method.getName());
return method.invoke(target, args);
});
-
JDK 동적 프록시 — 인터페이스 기반. 인터페이스가 있어야 한다
-
CGLIB — 클래스 상속 기반. 인터페이스가 없어도 된다
- final 클래스·final 메서드는 못 감싼다
-
프레임워크가 애노테이션을 처리하는 방식이 대개 이 둘 중 하나다
프록시인지 확인하는 법
System.out.println(bean.getClass());
// class com.example.OrderService$$SpringCGLIB$$0 ← 프록시다
Facade가 흔해지는 곳
-
레거시 시스템 앞에 두는 새 API
-
마이크로서비스 앞의 게이트웨이 (여러 서비스를 하나의 응답으로)
-
SDK 의 진입점 클래스
-
주의: 퍼사드가 계속 커지면 God Object 가 된다
- "창구" 이지 "모든 로직의 집합소" 가 아니다