How CGLIB Powers Faster Java Dynamic Proxies – Inside FastClass and Bytecode Generation

This article explains CGLIB, a high‑performance bytecode library for creating Java dynamic proxies without interfaces, walks through implementation steps and core source‑code analysis, details the FastClass optimization that bypasses reflection, and compares CGLIB with JDK dynamic proxies.

Xuanwu Backend Tech Stack
Xuanwu Backend Tech Stack
Xuanwu Backend Tech Stack
How CGLIB Powers Faster Java Dynamic Proxies – Inside FastClass and Bytecode Generation

CGLIB Introduction

CGLIB (Code Generation Library) is a high‑performance bytecode generation library used to create dynamic proxies for classes that do not implement interfaces by subclassing the target class and using method interception. It relies on ASM for bytecode manipulation.

GitHub: https://github.com/cglib/cglib

Maven dependency:

<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>3.3.1</version>
</dependency>

CGLIB Dynamic Proxy Implementation Steps

Prepare a target class without implementing an interface.

Implement net.sf.cglib.proxy.MethodInterceptor and override intercept to define custom logic.

Use Enhancer to create the proxy object.

public class UserService {
    public void addUser(String name) {
        System.out.println("添加用户: " + name);
    }
}

public class CglibInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("===执行cglib代理前置方法===");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("===执行cglib代理后置方法===");
        return result;
    }
}

public class CglibDynamicProxyTest {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);
        enhancer.setCallback(new CglibInterceptor());
        UserService proxy = (UserService) enhancer.create();
        proxy.addUser("qingyu");
    }
}

Running result:

===执行cglib代理前置方法===
添加用户: qingyu
===执行cglib代理后置方法===

CGLIB Dynamic Proxy Source Code Analysis

The proxy class is generated by Enhancer and instantiated via Enhancer.create(). The analysis starts from Enhancer#create, which sets the superclass and callback, then delegates to AbstractClassGenerator#create to handle caching and bytecode generation.

Enhancer#create

Two main calls: enhancer.setSuperclass() defines the target class. enhancer.setCallback() registers a Callback (usually MethodInterceptor).

AbstractClassGenerator#create

Looks up a global cache; if missing, creates a new ClassLoaderData and generates the proxy class bytecode using ASM. The bytecode is defined with ReflectUtils.defineClass and wrapped as a cached class.

DefaultGeneratorStrategy#generate

Uses ClassVisitor (via ClassEmitter) to emit class, fields, and methods. Key steps include defining fields like BOUND_FIELD, generating method bodies, and handling constructors.

FastClass Mechanism

To avoid reflection overhead, CGLIB generates a FastClass that maps each method to an integer index. The first proxy method call triggers FastClass creation; subsequent calls use the index to invoke the target method directly via FastClass.invoke.

Core methods: getIndex() returns the method’s index. invoke(int index, Object obj, Object[] args) calls the method without reflection.

Advantages: higher performance for frequently called methods. Drawbacks: additional generated classes increase memory usage.

JDK Dynamic Proxy vs CGLIB Dynamic Proxy

Proxy type : JDK proxies work only for interfaces; CGLIB can proxy any non‑final class.

Implementation : JDK uses java.lang.reflect.Proxy; CGLIB generates subclasses with ASM.

Performance : CGLIB is generally faster due to FastClass, though it incurs bytecode generation cost.

Use cases : JDK for interface‑based AOP; CGLIB for class‑based enhancements or when no interface is present.

Limitations : Both cannot proxy final classes or final methods.

Next topic: the principle of @Transactional.

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.

JavaAOPDynamic ProxyBytecode GenerationcglibFastClass
Xuanwu Backend Tech Stack
Written by

Xuanwu Backend Tech Stack

Primarily covers fundamental Java concepts, mainstream frameworks, deep dives into underlying principles, and JVM internals.

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.