Master Java Proxy Pattern: Static, JDK Dynamic & CGLIB Implementations
This article explains the proxy design pattern in Java, covering static proxy, JDK dynamic proxy, and CGLIB dynamic proxy implementations with code examples, diagrams, and a comparison of their advantages, limitations, and use‑case differences.
Introduction
Proxy pattern is a fundamental design pattern that provides a surrogate to control access to another object, serving as the basis for many framework features.
Java's Three Proxy Implementations
Java implements the proxy pattern via two main categories: static proxy and dynamic proxy, the latter further divided into JDK dynamic proxy and CGLIB dynamic proxy.
Static Proxy
Static proxy requires the proxy class to implement the same interface as the target class.
Interface: ISolver
Target class: Solver
Proxy class: SolverProxy
Client
Output
Static proxy can extend functionality without modifying the target, but it introduces redundancy and maintenance overhead because the proxy must implement the same interface.
JDK Dynamic Proxy
JDK dynamic proxy uses Java reflection to create proxy objects at runtime.
Key APIs: java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler.
<code>public class ProxyFactory {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("请问有什么可以帮到您?");
Object returnValue = method.invoke(target, args);
System.out.println("问题已经解决啦!");
return null;
}
}
);
}
}
</code> <code>public class Client {
public static void main(String[] args) {
ISolver developer = new Solver();
ISolver csProxy = (ISolver) new ProxyFactory(developer).getProxyInstance();
csProxy.solve();
}
}
</code>Output:
<code>请问有什么可以帮到您?
疯狂掉头发解决问题……
问题已经解决啦!
</code>CGLIB Dynamic Proxy
CGLIB (Code Generation Library) creates subclasses at runtime, allowing proxying without requiring interfaces.
<code>public class ProxyFactory implements MethodInterceptor {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance() {
Enhancer en = new Enhancer();
en.setSuperclass(target.getClass());
en.setCallback(this);
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("请问有什么可以帮到您?");
Object returnValue = method.invoke(target, args);
System.out.println("问题已经解决啦!");
return null;
}
}
</code> <code>public class Client {
public static void main(String[] args) {
Solver developer = new Solver();
Solver csProxy = (Solver) new ProxyFactory(developer).getProxyInstance();
csProxy.solve();
}
}
</code>Output:
<code>请问有什么可以帮到您?
疯狂掉头发解决问题……
问题已经解决啦!
</code>Key Differences
Static proxy is compiled into a concrete class; dynamic proxies are generated at runtime.
JDK dynamic proxy requires the target to implement one or more interfaces, while CGLIB works with concrete classes but cannot proxy final methods.
Sanyou's Java Diary
Passionate about technology, though not great at solving problems; eager to share, never tire of learning!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.