CGLIB与JDK动态代理不同之处说明
下文笔者讲述 CGLIB与JDK动态代理 不同之处,如下所示
CGLIB与JDK动态代理比较
| 特性 | JDK 动态代理 | CGLIB 动态代理 | |---------------------|---------------------------------------------------|---------------------------------------------------| | 代理对象类型 | 代理接口 | 代理类(继承目标类) | | 目标类要求 | 目标类必须实现至少一个接口 | 目标类可以不实现接口,但不能是 `final` 的 | | 性能 | 通常比 CGLIB 慢,因为需要通过反射调用接口方法 | 通常比 JDK 动态代理快,因为直接调用方法 | | 使用场景 | 代理接口实现 | 代理类实现,特别是没有实现接口的类 | | 字节码操作 | 使用反射 | 使用 ASM 进行字节码操作 |
使用CGLIB代理类
1.定义目标类
public class TargetClass {
public void sayHello() {
System.out.println("Hello from TargetClass!");
}
}
2.定义拦截器
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method: " + method.getName());
return result;
}
}
3.创建代理类并使用
import net.sf.cglib.proxy.Enhancer;
public class CglibExample {
public static void main(String[] args) {
// 创建 Enhancer 对象
Enhancer enhancer = new Enhancer();
// 设置目标类
enhancer.setSuperclass(TargetClass.class);
// 设置拦截器
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理类的实例
TargetClass proxyInstance = (TargetClass) enhancer.create();
// 调用代理类的方法
proxyInstance.sayHello();
}
}
代码说明
1.定义目标类
public class TargetClass {
public void sayHello() {
System.out.println("Hello from TargetClass!");
}
}
- `TargetClass`:目标类,包含要代理的方法 `sayHello`。
2.定义拦截器:
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method: " + method.getName());
return result;
}
}
- `MyMethodInterceptor`:实现 `MethodInterceptor` 接口。
- `intercept` 方法:在目标方法调用前后添加额外的逻辑。
3.创建代理类并使用:
import net.sf.cglib.proxy.Enhancer;
public class CglibExample {
public static void main(String[] args) {
// 创建 Enhancer 对象
Enhancer enhancer = new Enhancer();
// 设置目标类
enhancer.setSuperclass(TargetClass.class);
// 设置拦截器
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理类的实例
TargetClass proxyInstance = (TargetClass) enhancer.create();
// 调用代理类的方法
proxyInstance.sayHello();
}
}
-创建 `Enhancer` 对象:
`Enhancer` 是 CGLIB 的核心类,
用于生成代理类。
-设置目标类:
`enhancer.setSuperclass(TargetClass.class)`
设置要代理的目标类。
-设置拦截器:
`enhancer.setCallback(new MyMethodInterceptor())`
设置拦截器。
-创建代理类的实例:
`enhancer.create()`
创建代理类的实例。
-调用代理类的方法:
`proxyInstance.sayHello()`调用代理类的方法,
拦截器会在方法调用前后添加额外的逻辑
代码输出信息
Before method: sayHello Hello from TargetClass! After method: sayHello
内部实现细节
1.生成代理类:
- CGLIB 使用 ASM 库生成目标类的子类。
- 生成的子类会重写目标类的方法。
2.拦截器调用:
- 当代理类的方法被调用时
会先调用拦截器`intercept` 方法。
- 在 `intercept` 方法中
可以添加额外的逻辑(如日志记录、权限检查等)。
- 使用 `MethodProxy.invokeSuper` 调用目标类的方法。
3.字节码操作:
- CGLIB 使用 ASM 库进行字节码操作,
生成新的类文件。
- 生成的类文件会在运行时加载到JVM 中
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


