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 中
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。