The proxy pattern is a foundational concept for understanding the underlying mechanics of Spring AOP. It allows you to control access to an object by providing a surrogate or placeholder.
Static Proxy
In a static proxy implementation, the proxy class is created manually or by specific tools before compilation.
Core Components:
- Subject Interface: Defines the common operations for the real object and the proxy.
- Real Subject: The actual object performing the business logic.
- Proxy: Contains a rfeerence to the real subject and controls access, often adding cross-cutting concerns.
- Client: Interacts with the system via the proxy.
Example Implementation:
- Define the service contract:
public interface DataService {
void create();
void remove();
void modify();
void retrieve();
}
- Implement the concrete service:
public class DataServiceImpl implements DataService {
@Override
public void create() {
System.out.println("Creating data entry");
}
@Override
public void remove() {
System.out.println("Removing data entry");
}
@Override
public void modify() {
System.out.println("Modifying data entry");
}
@Override
public void retrieve() {
System.out.println("Retrieving data entry");
}
}
- Create the static proxy:
public class DataServiceProxy implements DataService {
private DataServiceImpl targetService;
public void setTargetService(DataServiceImpl targetService) {
this.targetService = targetService;
}
@Override
public void create() {
audit("create");
targetService.create();
}
@Override
public void remove() {
audit("remove");
targetService.remove();
}
@Override
public void modify() {
audit("modify");
targetService.modify();
}
@Override
public void retrieve() {
audit("retrieve");
targetService.retrieve();
}
private void audit(String operation) {
System.out.println("Audit log: " + operation);
}
}
- Client usage:
public class Application {
public static void main(String[] args) {
DataServiceProxy proxy = new DataServiceProxy();
proxy.setTargetService(new DataServiceImpl());
proxy.create();
}
}
Advantages:
- Isolates business logic from auxiliary tasks (like logging or security).
- Facilitates centralized management of cross-cutting concerns.
Disadvantages:
- Leads to code duplication; a new proxy class is required for every real subject.
Dynamic Proxy
Dynamic proxies generate proxy classes at runtime rather than at compile-time.
Characteristics:
- Shares the same role structure as static proxies.
- The proxy class is generated dynamically.
Categories:
- Interface-based (JDK Dynamic Proxy): Uses
java.lang.reflect.ProxyandInvocationHandler. - Class-based (CGLIB): Generates subclasses of the target class.
- Bytecode manipulation (e.g., Javassist).
Key Classes:
Proxy: Provides static methods to create dynamic proxy instances.InvocationHandler: The interface implemented to define the bheavior of the proxy.
Advantages:
- A single dynamic proxy handler can manage multiple interfaces or classes.
- Reduces the need to write specific proxy classes for every service, making the code more maintainable.