cglib通过字节码生成目标类的子类实现代理,需引入依赖、使用enhancer指定父类并设置methodinterceptor回调,目标类及方法不能为final。

CGLIB(Code Generation Library)可以为没有实现接口的类创建动态代理,原理是通过字节码技术生成目标类的子类,在子类中重写方法并插入拦截逻辑。使用前需引入依赖,核心是 Enhancer 类和 MethodInterceptor 回调。
添加 CGLIB 依赖
如果是 Maven 项目,在 pom.xml 中添加:
<dependency><groupid>cglib</groupid><artifactid>cglib</artifactid><version>3.3.0</version></dependency>
注意:CGLIB 依赖 ASM,新版(如 3.3.0)已内置,无需额外引入。
定义被代理的目标类(无接口)
例如一个普通类,不实现任何接口:
public class UserService {
public void save() {
System.out.println("保存用户");
}
public String getName() {
return "Tom";
}
}
该类没有接口,无法用 JDK 动态代理,但适合 CGLIB。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
编写 MethodInterceptor 实现方法拦截
实现 MethodInterceptor 接口,重写 intercept 方法,在其中控制原方法调用、添加前置/后置逻辑:
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class LogInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("[前置] 调用方法: " + method.getName());
Object result = proxy.invokeSuper(obj, args); // 注意:调用父类(目标类)方法,不是 method.invoke()
System.out.println("[后置] 方法执行完成");
return result;
}
}
关键点:
- 必须用
proxy.invokeSuper(obj, args)调用原始方法,不能用method.invoke(obj, args)(会触发无限递归) -
obj是 CGLIB 生成的子类实例,proxy封装了对父类方法的高效调用 - 目标类不能是
final类,方法也不能是final,否则 CGLIB 无法继承/重写
使用 Enhancer 创建代理对象
配置 Enhancer,指定父类和回调,生成代理实例:
import net.sf.cglib.proxy.Enhancer;
public class CglibDemo {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class); // 指定父类
enhancer.setCallback(new LogInterceptor()); // 设置拦截器
UserService proxy = (UserService) enhancer.create(); // 创建代理对象
proxy.save(); // 输出前置/后置日志 + “保存用户”
System.out.println(proxy.getName()); // 同样被拦截
}
}
补充说明:
- 可调用
enhancer.setClassLoader(...)指定类加载器(如当前线程上下文类加载器) - 若目标类有构造函数且需传参,可用
enhancer.setConstructorArgs(...)和enhancer.setConstructorTypes(...) - CGLIB 生成的代理类名形如
UserService$$EnhancerByCGLIB$$xxx
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










