Static vs Dynamic Proxy in Java: When and How to Use Each
This article explains the differences between static and dynamic proxies in Java, demonstrates how to implement static proxies, JDK dynamic proxies, and CGLib proxies with complete code examples, and compares their advantages, limitations, and typical use cases in backend development.
1. Static Proxy vs Dynamic Proxy
Proxy classes can enhance the methods of the target object. They are divided into static proxies and dynamic proxies.
1.1 Static Proxy
Static proxy: the proxy class must be declared in source code.
public class TestStaticProxy {
public static void main(String[] args) {
IRegisterService iRegisterService = new RegisterServiceImpl();
IRegisterService proxy = new RegisterServiceProxy(iRegisterService);
proxy.register("RyanLee", "123");
}
}
interface IRegisterService {
void register(String name, String pwd);
}
class RegisterServiceImpl implements IRegisterService {
@Override
public void register(String name, String pwd) {
System.out.println(String.format("【向数据库中插入数据】name:%s,pwd:%s", name, pwd));
}
}
class RegisterServiceProxy implements IRegisterService {
IRegisterService iRegisterService;
public RegisterServiceProxy(IRegisterService iRegisterService) {
this.iRegisterService = iRegisterService;
}
@Override
public void register(String name, String pwd) {
System.out.println("[Proxy]一些前置处理");
System.out.println(String.format("[Proxy]打印注册信息:姓名:%s,密码:%s", name, pwd));
iRegisterService.register(name, pwd);
System.out.println("[Proxy]一些后置处理");
}
}Execution result:
[Proxy]一些前置处理
[Proxy]打印注册信息:姓名:RyanLee,密码:123
【向数据库中插入数据】name:RyanLee,pwd:123
[Proxy]一些后置处理1.2 Dynamic Proxy
Dynamic proxy: no need to declare a proxy class. It uses reflection and bytecode generation to create a subclass of the specified interface or class at runtime, allowing non‑intrusive enhancement of code.
Dynamic proxy can be implemented in two main ways:
JDK native dynamic proxy
CGLib dynamic proxy (Code Generation Library)
2. Implementation of Dynamic Proxy
2.1 JDK Native Dynamic Proxy
The dynamic proxy class and the target class must implement the same interface. JDK dynamic proxy can only proxy methods declared in the interface.
2.1.1 Proxy
java.lang.reflect.Proxyis the parent class of all dynamic proxies. It creates proxy class objects and instances via the static method newProxyInstance().
2.1.2 InvocationHandler
Each dynamic proxy instance is associated with an InvocationHandler. Method calls on the proxy are forwarded to the handler's invoke method.
2.1.3 Example
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestJdkDynamicProxy {
public static void main(String[] args) {
IRegisterService iRegisterService = new RegisterServiceImpl();
InsertDataHandler insertDataHandler = new InsertDataHandler();
IRegisterService proxy = (IRegisterService) insertDataHandler.getProxy(iRegisterService);
proxy.register("RyanLee", "123");
}
}
class InsertDataHandler implements InvocationHandler {
Object obj;
public Object getProxy(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
doBefore();
Object result = method.invoke(obj, args);
doAfter();
return result;
}
private void doBefore() {
System.out.println("[Proxy]一些前置处理");
}
private void doAfter() {
System.out.println("[Proxy]一些后置处理");
}
}Execution result:
[Proxy]一些前置处理
【向数据库中插入数据】name:RyanLee,pwd:123
[Proxy]一些后置处理2.2 CGLib Dynamic Proxy
CGLib (Code Generation Library) is a bytecode generation library based on ASM. It creates proxies by subclassing the target class.
2.2.1 Enhancer
Enhancer specifies the target object to proxy. The create method returns the proxy instance. Method calls on non‑final methods are intercepted by MethodInterceptor.
2.2.2 MethodInterceptor
The interceptor’s intercept method receives the method call, allowing pre‑ and post‑processing.
2.2.3 Example
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class TestCGLibDynamicProxy {
public static void main(String[] args) {
IRegisterService iRegisterService = new RegisterServiceImpl();
InsertDataInterceptor interceptor = new InsertDataInterceptor();
RegisterServiceImpl proxy = (RegisterServiceImpl) interceptor.getProxy(iRegisterService);
proxy.register("RyanLee", "123");
}
}
class InsertDataInterceptor implements MethodInterceptor {
Object target;
public Object getProxy(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
private void doBefore() {
System.out.println("[Proxy]一些前置处理");
}
private void doAfter() {
System.out.println("[Proxy]一些后置处理");
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
doBefore();
Object result = methodProxy.invoke(target, args);
doAfter();
return result;
}
}Execution result:
[Proxy]一些前置处理
【向数据库中插入数据】name:RyanLee,pwd:123
[Proxy]一些后置处理2.3 JDK Dynamic Proxy vs CGLib Dynamic Proxy
The main differences are:
JDK dynamic proxy requires the target to implement an interface; it can only proxy interface methods.
CGLib creates a subclass of the target class, allowing proxy of concrete classes without interfaces.
Spring’s default proxy mechanism uses JDK dynamic proxies; it can be switched to CGLib by changing configuration, and it is generally recommended not to place Spring annotations on interfaces when CGLib is needed.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
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.
