CGLIB动态代理通过继承目标类生成子类实现代理,基于ASM字节码增强,重写非final方法并插入MethodInterceptor拦截逻辑;目标类及方法不可为final,否则因JVM继承限制抛出异常。

CGLIB 动态代理通过继承目标类生成子类代理,核心是利用字节码增强技术(基于 ASM)在运行时动态创建目标类的子类,并重写其非 final 方法,插入拦截逻辑。
代理类如何继承目标类
CGLIB 会扫描目标类的 public、protected 方法(不处理 private 和 final 方法),生成一个继承自该类的新类(如 TargetClass$$EnhancerByCGLIB$$xxx)。这个子类覆盖了所有可重写的方法,并在方法调用前后插入 MethodInterceptor 的逻辑。
- 目标类不能是 final —— 否则无法被继承,CGLIB 抛出异常
- 目标类的构造方法需为 public 或 protected —— 子类需能调用父类构造器
- final 方法不会被代理 —— CGLIB 只重写非 final 方法,调用时直接执行原逻辑
关键组件:Enhancer 与 MethodInterceptor
Enhancer 是 CGLIB 的核心类,负责配置和生成代理子类;MethodInterceptor 定义拦截行为,类似 JDK 动态代理中的 InvocationHandler。
- 调用
enhancer.setSuperclass(Target.class)指定父类 - 调用
enhancer.setCallback(interceptor)设置拦截器 -
intercept()方法中可通过method.invokeSuper(obj, args)调用父类原始方法
为什么不能代理 final 类或方法
Java 语法规定 final 类不可被继承,final 方法不可被重写。CGLIB 生成子类依赖于 JVM 的继承机制,一旦目标类或方法被声明为 final,字节码生成阶段就会失败,抛出 IllegalArgumentException 或 CodeGenerationException。
立即学习“Java免费学习笔记(深入)”;
- 常见报错提示:“Cannot subclass final class xxx” 或 “Unable to create proxy for final method”
- 解决方式:去掉 final 修饰符,或改用 JDK 动态代理(前提是目标类实现了接口)
与 JDK 动态代理的本质区别
JDK 代理基于接口,生成的是实现相同接口的代理类;CGLIB 基于继承,生成的是目标类的子类。因此:
- CGLIB 不要求目标类实现接口,适合没有接口的类
- CGLIB 代理对象是目标类的子类实例,
instanceof判定仍为原类型 - 由于使用继承,构造函数会被执行两次(父类 + 子类),需注意初始化副作用


















