Backend Development 10 min read

Static vs Dynamic Proxy in Java: Implementation, Execution Results, and Comparison

This article explains the differences between static and dynamic proxies in Java, provides complete code examples for static proxy, JDK native dynamic proxy, and CGLib dynamic proxy, shows their execution results, and compares their usage scenarios, especially in backend development.

Top Architect
Top Architect
Top Architect
Static vs Dynamic Proxy in Java: Implementation, Execution Results, and Comparison

1. Static Proxy vs Dynamic Proxy

Proxy classes can enhance the methods of a target object. They are divided into static proxies, which require a manually written proxy class, and dynamic proxies, which are generated at runtime.

1.1 Static Proxy

Static proxy: the source code must declare a proxy class.

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 byte‑code generation to create a subclass (the proxy class) and its instance at runtime, allowing non‑intrusive enhancement of code.

Two main implementations:

JDK native dynamic proxy

CGLib dynamic proxy

2.1 JDK Native Dynamic Proxy

The proxy class and the target class must implement the same interface; only methods declared in the interface can be proxied.

2.1.1 Proxy

java.lang.reflect.Proxy is the base class for all dynamic proxies. The static method newProxyInstance() creates the proxy class and its instance.

2.1.2 InvocationHandler

Each proxy instance is associated with an InvocationHandler . Method calls on the proxy are forwarded to the handler's invoke method.

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 byte‑code generation library based on ASM. It creates a subclass of the target class at runtime to achieve proxying.

2.2.1 Enhancer

Enhancer specifies the target object to proxy. Calling create() returns the proxy instance. Method calls on non‑final methods are intercepted by a MethodInterceptor .

2.2.2 MethodInterceptor

The interceptor’s intercept method receives the method invocation, allowing pre‑ and post‑processing.

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 o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        doBefore();
        Object result = methodProxy.invoke(target, objects);
        doAfter();
        return result;
    }
}

Execution result:

[Proxy]一些前置处理
【向数据库中插入数据】name:RyanLee,pwd:123
[Proxy]一些后置处理

2.3 Comparison

The biggest difference is that JDK dynamic proxy requires the target to implement an interface, while CGLib proxies by subclassing the concrete class, allowing it to proxy classes without interfaces. Spring’s default proxy mechanism uses JDK dynamic proxy, but can be switched to CGLib.

Feel free to discuss, ask questions, or share your own experiences.

backendJavaProxyJDKDynamic ProxyStatic ProxyCglib
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.