CGLib 动态代理实现CGLIB (Code Generation Library) 是一个基于 ASM 的字节码生成库,它允许我们在运行时对字节码进行修改、和动态生成 CGLIB 通过继承方式实现代理 。
![附:2种实现方式详细对比 Java 动态代理原理图解](http://img.zhejianglong.com/231019/0649132131-9.png)
文章插图
在使用 CGLib 之前,我们要先在项目中引入 CGLib 框架 , 在 pom.xml 中添加如下配置:
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency>
![附:2种实现方式详细对比 Java 动态代理原理图解](https://m.360buyimg.com/jdcms/jfs/t1/213780/40/22846/43/635f3cc8Ec18d67aa/6e7d8fcc026a92ea.gif)
文章插图
![附:2种实现方式详细对比 Java 动态代理原理图解](https://m.360buyimg.com/jdcms/jfs/t1/213780/40/22846/43/635f3cc8Ec18d67aa/6e7d8fcc026a92ea.gif)
文章插图
CGLib 的实现代码:
package com.mikechen.proxydemo; import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CGLibExample { static class Car {public void running() {System.out.println("The car is running.");}} /*** CGLib 代理类*/static class CGLibProxy implements MethodInterceptor {private Object target; // 代理对象 public Object getInstance(Object target) {this.target = target;Enhancer enhancer = new Enhancer();// 设置父类为实例类enhancer.setSuperclass(this.target.getClass());// 回调方法enhancer.setCallback(this);// 创建代理对象return enhancer.create();} @Overridepublic Object intercept(Object o, Method method,Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("方法调用前业务处理.");Object result = methodProxy.invokeSuper(o, objects); // 执行方法调用return result;}} // 执行 CGLib 的方法调用public static void main(String[] args) {// 创建 CGLib 代理类CGLibProxy proxy = new CGLibProxy();// 初始化代理对象Car car = (Car) proxy.getInstance(new Car());// 执行方法car.running();
![附:2种实现方式详细对比 Java 动态代理原理图解](https://m.360buyimg.com/jdcms/jfs/t1/213780/40/22846/43/635f3cc8Ec18d67aa/6e7d8fcc026a92ea.gif)
文章插图
![附:2种实现方式详细对比 Java 动态代理原理图解](https://m.360buyimg.com/jdcms/jfs/t1/213780/40/22846/43/635f3cc8Ec18d67aa/6e7d8fcc026a92ea.gif)
文章插图
以上程序的执行结果是:
方法调用前业务处理 。
The car is running.
![附:2种实现方式详细对比 Java 动态代理原理图解](https://m.360buyimg.com/jdcms/jfs/t1/213780/40/22846/43/635f3cc8Ec18d67aa/6e7d8fcc026a92ea.gif)
文章插图
![附:2种实现方式详细对比 Java 动态代理原理图解](https://m.360buyimg.com/jdcms/jfs/t1/213780/40/22846/43/635f3cc8Ec18d67aa/6e7d8fcc026a92ea.gif)
文章插图
可以看出:
CGLib 和 JDK Proxy 的实现代码比较类似,都是通过实现代理器的接口,再调用某一个方法完成动态代理的 。
唯一不同的是,CGLib 在初始化被代理类时,是通过 Enhancer 对象把代理对象设置为被代理类的子类,来实现动态代理的 。
因此 , 被代理类不能被关键字 final 修饰,如果被 final 修饰,再使用 Enhancer 设置父类时会报错 , 动态代理的构建会失败 。
JDK 动态代理与 CGLib 的区别1. JDK 动态代理具体实现原理
- 通过实现 InvocationHandler 接口,创建自己的调用处理器;
- 通过为 Proxy 类指定 ClassLoader 对象和一组 interface , 来创建动态代理;
- 通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型;
- 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入 。
CGLib 是一个强大、高性能的 Code 生产类库,可以实现运行期动态扩展 java 类,Spring 在运行期间通过 CGlib 继承要被动态代理的类 , 重写父类的方法,实现 AOP 面向切面编程 。
3. 两者对比
- JDK 动态代理是面向接口的 。
- CGLib 动态代理是通过字节码底层继承要代理类来实现(如果被代理类被 final 关键字所修饰 , 会失败) 。
- CGLib 所创建的动态代理对象,在实际运行时候的性能要比 JDK 动态代理高不少,有研究表明,大概要高出10倍;
- CGLib 在创建对象的时候所花费的时间,比 JDK 动态代理要多很多,有研究表明,大概要高出8倍 。
【附:2种实现方式详细对比 Java 动态代理原理图解】以上,是关于 Java 动态代理原理、以及动态代理2 种实现方式的解析 。
推荐阅读
- 深度剖析Java的volatile实现原理,再也不怕面试官问了
- Spring Cloud 整合 nacos 实现动态配置中心
- 【保姆教程】RuoYi-Radius搭建实现portal认证
- 关于网页实现串口或者TCP通讯的说明
- 你给文字描述,AI艺术作画,精美无比!附源码,快来试试!
- .net core Blazor+自定义日志提供器实现实时日志查看器
- 九 前后端分离项目:实现"添加"功能(后端接口)
- 小样本利器4. 正则化+数据增强 Mixup Family代码实现
- 电脑中随机附带的游戏空当接龙怎么玩(单机游戏空当接龙怎么玩)
- node.js:《接口实现文件的上传和下载》