Proxy Design Pattern in Java
Learn Proxy Design Pattern in Java with Virtual Proxy, Protection Proxy, Remote Proxy, Smart Proxy, Spring AOP examples, caching, security, lazy loading, real-world use cases, and interview questions.
What You Will Learn
In this article, you'll learn:
- What is Proxy Pattern?
- Why Proxy Pattern is Needed
- Virtual Proxy
- Protection Proxy
- Remote Proxy
- Smart Proxy
- UML Diagrams
- Java Implementation
- Spring AOP Examples
- Hibernate Lazy Loading
- Enterprise Use Cases
- Benefits and Limitations
- Interview Questions
Introduction
Imagine you want to access:
Bank Account
Should every user directly access it?
Probably not.
We may need:
Authentication
Authorization
Caching
Logging
Lazy Loading
Monitoring
Before allowing access.
Instead of exposing the real object directly:
Client
↓
Proxy
↓
Real Object
The Proxy controls access.
What is Proxy Pattern?
Proxy is a Structural Design Pattern that provides a placeholder or representative object that controls access to another object.
The proxy sits between:
Client
and
Real Object
Purpose of Proxy Pattern
The main goal is:
Control Access
Without Modifying
The Original Object
Real World Analogy
Think about a credit card.
You do not directly carry money from the bank.
Instead:
You
↓
Credit Card
↓
Bank Account
The card acts as a proxy.
Proxy Architecture
flowchart LR
Client --> Proxy
Proxy --> RealService
Client never talks directly to the real service.
Problem Without Proxy
flowchart LR
Client --> Database
Client --> PaymentService
Client --> FileSystem
No security.
No validation.
No monitoring.
Solution With Proxy
flowchart LR
Client --> Proxy
Proxy --> Database
Proxy --> PaymentService
Proxy --> FileSystem
Proxy adds control.
Key Components
Subject
Common interface.
Real Subject
Actual implementation.
Proxy
Controls access to real object.
Client
Uses the proxy.
UML Diagram
classDiagram
class Subject {
<<interface>>
+request()
}
class RealService
class Proxy
Subject <|.. RealService
Subject <|.. Proxy
Proxy --> RealService
Real World Banking Example
Money Transfer
Before transfer:
Authenticate User
Check Permissions
Validate Account
Audit Request
Transfer Money
Proxy performs validation.
Step 1: Subject Interface
public interface PaymentService {
void processPayment(
double amount);
}
Step 2: Real Service
public class PaymentServiceImpl
implements PaymentService {
@Override
public void processPayment(
double amount) {
System.out.println(
"Processing Payment: "
+ amount);
}
}
Step 3: Proxy Class
public class PaymentProxy
implements PaymentService {
private final PaymentService service =
new PaymentServiceImpl();
@Override
public void processPayment(
double amount) {
System.out.println(
"Validating User");
service.processPayment(
amount);
System.out.println(
"Audit Logged");
}
}
Client Code
public class ProxyDemo {
public static void main(
String[] args) {
PaymentService service =
new PaymentProxy();
service.processPayment(
1000);
}
}
Output
Validating User
Processing Payment: 1000
Audit Logged
Execution Flow
sequenceDiagram
Client->>Proxy: processPayment()
Proxy->>Proxy: Validate User
Proxy->>RealService: processPayment()
RealService-->>Proxy: Success
Proxy-->>Client: Response
Types of Proxy Pattern
There are four major proxy types.
flowchart TD
A[Proxy Pattern]
A --> B[Virtual Proxy]
A --> C[Protection Proxy]
A --> D[Remote Proxy]
A --> E[Smart Proxy]
Virtual Proxy
Used for:
Lazy Loading
Object creation is delayed until needed.
Example
Suppose:
High Resolution Image
500 MB
Loading immediately is expensive.
Virtual Proxy loads only when requested.
Virtual Proxy Diagram
flowchart LR
Client
-->
ImageProxy
-->
RealImage
Real image loads lazily.
Image Example
public class ImageProxy
implements Image {
private RealImage image;
@Override
public void display() {
if (image == null) {
image =
new RealImage();
}
image.display();
}
}
Hibernate Example
Hibernate Lazy Loading uses Virtual Proxy.
User user =
repository.findById(1L);
Associated objects:
user.getOrders();
load only when needed.
Protection Proxy
Controls access based on permissions.
Example
Admin User:
Allowed
Normal User:
Denied
Protection Proxy Flow
flowchart TD
User
--> Proxy
Proxy --> CheckRole
CheckRole --> Allow
CheckRole --> Deny
Banking Example
Only managers can:
Approve Loans
Close Accounts
Reverse Transactions
Proxy enforces security.
Remote Proxy
Represents an object in another system.
Example
Client:
San Antonio
Server:
New York
Proxy hides network communication.
Remote Proxy Architecture
flowchart LR
Client
--> RemoteProxy
--> RemoteServer
Real Examples
RMI
gRPC
SOAP
REST Clients
Smart Proxy
Adds extra behavior.
Examples:
Logging
Caching
Metrics
Monitoring
Tracing
Smart Proxy Example
public class LoggingProxy
implements Service {
@Override
public void execute() {
System.out.println(
"Start");
realService.execute();
System.out.println(
"End");
}
}
Caching Proxy Example
Without cache:
Database Query Every Time
With proxy:
Check Cache
↓
Return Cached Data
Cache Flow
flowchart TD
Request
--> CacheProxy
CacheProxy --> CacheHit
CacheProxy --> Database
Enterprise Examples
Banking
Transaction Validation
Audit Logging
Fraud Detection
Insurance
Claim Authorization
Policy Validation
Healthcare
Patient Access Control
Medical Record Security
Microservices
API Gateway
Authentication
Authorization
Spring AOP Example
Spring AOP uses Proxy Pattern extensively.
Example:
@Transactional
@Cacheable
@Async
@Retryable
Spring creates proxy objects behind the scenes.
Spring Architecture
flowchart LR
Client
-->
Spring Proxy
-->
Business Service
Dynamic Proxy
Java supports runtime proxies.
Proxy.newProxyInstance(...)
Used heavily in:
Spring
Hibernate
Feign Clients
JDK Dynamic Proxy Example
InvocationHandler
Intercepts method calls before reaching target.
Feign Client Example
@FeignClient(
name = "user-service"
)
Feign creates proxy implementations automatically.
Benefits
✅ Access Control
✅ Security
✅ Lazy Loading
✅ Logging
✅ Monitoring
✅ Caching
✅ Improved Performance
Limitations
❌ Extra Layer
❌ More Complexity
❌ Additional Memory
❌ Can Affect Debugging
When To Use
Use Proxy when:
- Access control is required
- Lazy loading is needed
- Remote communication exists
- Logging and monitoring are required
- Caching is beneficial
When Not To Use
Avoid Proxy when:
- Object access is simple
- Additional abstraction is unnecessary
Proxy vs Decorator
| Feature | Proxy | Decorator |
|---|---|---|
| Purpose | Control Access | Add Functionality |
| Focus | Protection | Enhancement |
| Usage | Security, Caching | Behavior Extension |
Proxy vs Facade
| Feature | Proxy | Facade |
|---|---|---|
| Purpose | Control Access | Simplify Complexity |
| Relationship | Same Interface | New Interface |
| Focus | Access Management | Usability |
Real Enterprise Architecture
flowchart TD
A[Client]
B[API Gateway]
C[Authentication Proxy]
D[Business Service]
E[Database]
A --> B
B --> C
C --> D
D --> E
Proxy layers secure the system.
Interview Questions
What is Proxy Pattern?
A structural design pattern that controls access to another object.
Why Use Proxy?
Security, lazy loading, caching, logging, and remote access.
What is Virtual Proxy?
A proxy that delays object creation until needed.
What is Protection Proxy?
A proxy that enforces authorization rules.
What is Remote Proxy?
A proxy representing an object in another location.
What is Smart Proxy?
A proxy that adds logging, caching, monitoring, or metrics.
Where Is Proxy Used In Spring?
Spring AOP, Transactions, Caching, Async Processing.
Real Java Example?
Hibernate Lazy Loading.
Key Takeaways
- Proxy is a Structural Design Pattern.
- Controls access to real objects.
- Supports security, caching, monitoring, and lazy loading.
- Four major types: Virtual, Protection, Remote, and Smart Proxy.
- Spring AOP heavily relies on proxies.
- Hibernate lazy loading is a classic proxy implementation.
- API Gateways often act as enterprise proxies.
- One of the most widely used patterns in modern Java applications.