Mastering Spring Dynamic Proxies: JDK vs CGLIB Explained

This article explains the concept of dynamic proxies, compares Spring's JDK‑based and CGLIB‑based proxy implementations with code examples, and shows how they power Spring AOP for cross‑cutting concerns such as transactions and logging.

Mike Chen's Internet Architecture
Mike Chen's Internet Architecture
Mike Chen's Internet Architecture
Mastering Spring Dynamic Proxies: JDK vs CGLIB Explained

Dynamic proxy is a runtime technique that generates proxy classes, allowing control over target objects without modifying them.

Spring uses dynamic proxies extensively for AOP, enabling cross‑cutting concerns such as transaction management and logging.

Spring supports two main proxy mechanisms: JDK dynamic proxy (interface‑based) and CGLIB proxy (subclass‑based).

JDK Dynamic Proxy

Works only for classes that implement interfaces. It requires an InvocationHandler implementation and the use of Proxy.newProxyInstance to create the proxy.

Steps:

Target class implements an interface.

Create an InvocationHandler with an invoke method.

Generate the proxy via Proxy.newProxyInstance.

public class DynamicProxy implements InvocationHandler {
    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before method");
        Object result = method.invoke(target, args);
        System.out.println("after method");
        return result;
    }

    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        DynamicProxy dynamicProxy = new DynamicProxy(realSubject);
        Subject subject = (Subject) Proxy.newProxyInstance(
                realSubject.getClass().getClassLoader(),
                realSubject.getClass().getInterfaces(),
                dynamicProxy);
        subject.doSomething();
    }
}

interface Subject {
    void doSomething();
}

class RealSubject implements Subject {
    @Override
    public void doSomething() {
        System.out.println("RealSubject do something.");
    }
}

CGLIB Dynamic Proxy

Based on subclassing, it can proxy any class, even those without interfaces, by generating bytecode at runtime using the CGLIB library.

public class UserService {
    public void addUser(String name) {
        System.out.println("add user: " + name);
    }
}

public class UserServiceProxy implements MethodInterceptor {
    private Object target;

    public UserServiceProxy(Object target) {
        this.target = target;
    }

    public Object createProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("before method: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("after method: " + method.getName());
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService();
        UserServiceProxy userServiceProxy = new UserServiceProxy(userService);
        UserService proxy = (UserService) userServiceProxy.createProxy();
        proxy.addUser("Tom");
    }
}

Spring automatically chooses the appropriate proxy type: if the target implements interfaces, it uses JDK dynamic proxy; otherwise it falls back to CGLIB.

These proxy mechanisms form the foundation of Spring AOP, allowing developers to weave additional behavior around business methods.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaaopspringDynamic ProxycglibJDK Proxy
Mike Chen's Internet Architecture
Written by

Mike Chen's Internet Architecture

Over ten years of BAT architecture experience, shared generously!

0 followers
Reader feedback

How this landed with the community

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.