在Java生态中,动态代理技术被广泛应用于日志记录、事务管理、权限校验等场景,CGLIB作为基于字节码增强的动态代理框架,能够在运行时动态生成目标类的子类来实现代理功能,不需要目标类实现任何接口,灵活性更高。

CGLIB核心原理
CGLIB的全称是Code Generation Library,它底层依赖ASM字节码操作框架,在运行时对目标类的字节码进行修改,生成目标类的子类作为代理类。当调用代理对象的方法时,会先进入MethodInterceptor的拦截逻辑,开发者可以在拦截逻辑中自定义增强操作,之后再决定是否调用目标类的方法。
环境准备
使用CGLIB需要先引入相关依赖,如果你使用Maven构建项目,可以在pom.xml中添加以下依赖:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
MethodInterceptor接口使用
MethodInterceptor是CGLIB中定义方法拦截逻辑的接口,我们需要实现这个接口来编写自定义的增强逻辑,接口中只有一个intercept方法,方法参数含义如下:
- Object o:生成的代理对象实例
- java.lang.reflect.Method method:被拦截的目标方法
- Object[] objects:目标方法的参数列表
- MethodProxy methodProxy:方法代理对象,用于调用目标类的方法
实现MethodInterceptor接口
下面是一个简单的MethodInterceptor实现示例,实现了方法调用前后的日志打印增强:
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class LogMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 方法调用前增强逻辑
System.out.println("方法" + method.getName() + "开始执行,参数:" + java.util.Arrays.toString(objects));
// 调用目标类的方法,methodProxy.invokeSuper表示调用父类即目标类的方法
Object result = methodProxy.invokeSuper(o, objects);
// 方法调用后增强逻辑
System.out.println("方法" + method.getName() + "执行结束,返回值:" + result);
return result;
}
}
生成代理对象
实现拦截器之后,需要使用CGLIB的Enhancer类来配置代理信息并生成代理对象,Enhancer是CGLIB中用于生成代理类的核心类,示例代码如下:
import net.sf.cglib.proxy.Enhancer;
public class CglibProxyTest {
// 目标类,不需要实现接口
static class UserService {
public String getUserInfo(String userId) {
return "用户ID:" + userId + ",用户名:测试用户";
}
}
public static void main(String[] args) {
// 创建Enhancer实例
Enhancer enhancer = new Enhancer();
// 设置父类,即目标类
enhancer.setSuperclass(UserService.class);
// 设置回调,即自定义的MethodInterceptor实现
enhancer.setCallback(new LogMethodInterceptor());
// 创建代理对象
UserService userServiceProxy = (UserService) enhancer.create();
// 调用代理对象的方法
String result = userServiceProxy.getUserInfo("1001");
System.out.println("代理调用结果:" + result);
}
}
运行上述代码,会先输出方法执行前后的日志,再输出方法返回值,说明代理增强逻辑生效。
CGLIB与JDK动态代理对比
为了让开发者更好地选择代理方案,下面从多个维度对比两种动态代理技术:
| 对比维度 | CGLIB动态代理 | JDK动态代理 |
|---|---|---|
| 代理要求 | 目标类不需要实现接口,不能是final类,方法不能是final的 | 目标类必须实现至少一个接口 |
| 实现原理 | 基于字节码增强,生成目标类的子类 | 基于反射,生成实现目标接口的代理类 |
| 性能表现 | 生成代理类速度较慢,调用代理方法速度较快 | 生成代理类速度较快,调用代理方法速度较慢 |
| 适用场景 | 目标类没有实现接口的场景,对方法调用性能要求高的场景 | 目标类实现了接口的场景,对代理类生成速度要求高的场景 |
注意事项
使用CGLIB时需要注意以下几点:
- 如果目标类是final类,或者目标方法是final方法,CGLIB无法生成子类,会直接抛出异常
- 尽量避免在intercept方法中调用代理对象的其他方法,否则可能会触发无限递归调用
- 在高并发场景下,Enhancer的创建成本较高,可以考虑缓存生成的代理类,减少重复创建的开销
CGLIBMethodInterceptor字节码增强Java动态代理修改时间:2026-07-08 19:33:13