Structural Patternshigh

Proxy Pattern

Provide a surrogate or placeholder for another object to control access to it. The proxy and the real object implement the same interface.

Memory anchor

Proxy = a bouncer at a club. Same door (interface), but the bouncer decides who gets in (access control), checks IDs (protection proxy), or tells you 'the DJ is setting up' until the real party starts (virtual/lazy proxy).

Expected depth

Four common proxy types: (1) Virtual proxy — lazy-initializes an expensive object (loads an image only when first rendered); (2) Protection proxy — checks access rights before delegating; (3) Remote proxy — represents a remote object (RMI stub, gRPC stub); (4) Caching proxy — caches results of expensive operations. Proxy is the structural backbone of AOP: Spring's @Transactional generates a dynamic proxy that wraps your service method with transaction management.

Deep — senior internals

In Java, dynamic proxies (java.lang.reflect.Proxy and CGLIB) generate proxy classes at runtime without writing boilerplate. Spring and Hibernate depend on this heavily. The internal mechanics: CGLIB creates a subclass of the proxied class and overrides methods; JDK dynamic proxy creates a proxy for interfaces only using reflection and an InvocationHandler. Proxy vs Decorator: structurally identical — both wrap an object with the same interface. Intent separates them: Decorator enriches behaviour; Proxy controls access, adds cross-cutting concerns (logging, security, transaction), or delays initialization. Proxy is also used for the Null Object pattern (a no-op proxy that implements the interface with empty implementations).

🎤Interview-ready answer

I use proxy most often for cross-cutting concerns without modifying the target class. A LoggingProxy implements the same service interface, wraps the real service, and logs every method call's duration and result. The client gets the proxy injected — it never knows. Lazy loading is another scenario: a HeavyReportProxy holds no data until the first call to getReport() — then it loads from the DB, caches, and returns. I always clarify: Proxy keeps the same interface and controls access; Decorator keeps the same interface and adds behaviour. The line is intent, not structure.

Common trap

JDK dynamic proxy only proxies interfaces — it cannot proxy a concrete class directly. CGLIB subclasses the concrete class, but final classes and final methods cannot be proxied. Know which Spring beans are not AOPable (final classes, @Configuration with proxyBeanMethods=false).

Related concepts