【动态代理】CGLIB 动态代理的使用及原理

JDK动态代理和CGLIB动态代理 在SpringAOP中基于动态代理实现功能的增强,也就是动态的生成代理类,在代理类中织入增强的逻辑然后调用目标对象的方法。动态代理中用的比较多的两种:JDK动态代理、CGLIB动态代理。 JDK动态代理 使用JDK的java.lang.reflect.Proxy类的newProxyInstance方法实现的代理。 用一个测试接口看下具体实现: public interface JdkProxyDemoService { void queryTrs(); } @Service public 阅读详情

1. CGLIB 动态代理介绍

什么是 CGLIB?

CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。

通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB 是一个好的选择。

CGLIB 的原理

CGLIB 原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是 final 的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。

CGLIB 底层:采用ASM字节码生成框架,使用字节码技术生成代理类,比使用 Java 反射效率要高。

2. CGLIB 动态代理使用

CGLIB 动态代理步骤:

  1. 引入 CGLIB 依赖
  2. 定义一个被代理类
  3. 定义一个拦截器并实现接口 MethodInterceptor
  4. 代理工厂类
  5. 通过代理对象调用方法

引入依赖:cglib-nodep-2.2.jar

Student:被代理类

public class Student {

    public void handOut() {
        System.out.println("学生交作业。");
    }
}

CglibProxy:拦截器

public class CglibProxy implements MethodInterceptor {

    /**
     * @param o: 代理对象
     * @param method: 被代理方法
     * @param params: 方法入参
     * @param methodProxy: CGLIB方法
     **/
    @Override
    public Object intercept(Object o, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
        System.out.println("【增强方法】代理对象正在执行的方法:" + method.getName());
        Object result = methodProxy.invokeSuper(o, params);
        return result;
    }
}

CglibProxyFactory:代理工厂类

public class CglibProxyFactory {

    public static Object creatCglibProxyObj(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        // 为加强器指定要代理的业务类(即为下面生成的代理类指定父类)
        enhancer.setSuperclass(clazz);
        // 设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法
        enhancer.setCallback(new CglibProxy());
        return enhancer.create();
    }

}

测试:

public class Test {

    public static void main(String[] args) {
        Student studentProxy = (Student)CglibProxyFactory.creatCglibProxyObj(Student.class);
        studentProxy.handOut();
    }

}

运行后,依旧可以增强原功能。

3. CGLIB 动态代理原理

上文中的是通过 enhancer.create 方法调用获取的代理对象,以此为入口深入探究一下 CGLIB 动态代理的实现原理。

Enhancer#create():

public Object create() {
    this.classOnly = false;
    this.argumentTypes = null;
    return this.createHelper();
}

Enhancer#createHelper():调用父类的 create() 方法

private Object createHelper() {
    //...

    return super.create(KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), 
    		this.filter, this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID));
}

AbstractClassGenerator#create():

protected Object create(Object key) {
    try {
        //...
            if (gen == null) {
            	// 1.生成代理类 
                byte[] b = this.strategy.generate(this);
                // 2.获取代理类名称
                String className = ClassNameReader.getClassName(new ClassReader(b));
                this.getClassNameCache(loader).add(className);
                gen = ReflectUtils.defineClass(className, b, loader);
            }

            if (this.useCache) {
                ((Map)cache2).put(key, new WeakReference(gen));
            }

            var24 = this.firstInstance(gen);
        } finally {
            CURRENT.set(save);
        }

        return var24;
    }
    //...
}

DefaultGeneratorStrategy#generate():生成代理类

public byte[] generate(ClassGenerator cg) throws Exception {
    ClassWriter cw = this.getClassWriter();
    this.transform(cg).generateClass(cw);
    return this.transform(cw.toByteArray());
}

DebuggingClassWriter#toByteArray():

public byte[] toByteArray() {
    return (byte[])((byte[])AccessController.doPrivileged(new PrivilegedAction() {
        public Object run() {
            byte[] b = DebuggingClassWriter.super.toByteArray();
            if (DebuggingClassWriter.debugLocation != null) {
                String dirs = DebuggingClassWriter.this.className.replace('.', File.separatorChar);

                try {
                	// 如果 DebuggingClassWriter.DEBUG_LOCATION_PROPERTY 系统属性被设置,则输出代理类到指定目录
                    (new File(DebuggingClassWriter.debugLocation + File.separatorChar + dirs)).getParentFile().mkdirs();
                    File file = new File(new File(DebuggingClassWriter.debugLocation), dirs + ".class");
                    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));

                    try {
                        out.write(b);
                    } finally {
                        out.close();
                    }

                    if (DebuggingClassWriter.traceEnabled) {
                        file = new File(new File(DebuggingClassWriter.debugLocation), dirs + ".asm");
                        out = new BufferedOutputStream(new FileOutputStream(file));

                        try {
                            ClassReader cr = new ClassReader(b);
                            PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
                            TraceClassVisitor tcv = new TraceClassVisitor((ClassVisitor)null, pw);
                            cr.accept(tcv, 0);
                            pw.flush();
                        } finally {
                            out.close();
                        }
                    }
                } catch (IOException var17) {
                    throw new CodeGenerationException(var17);
                }
            }

            return b;
        }
    }));
}

生成 CGLIB 字节码文件

由上文可知,把 DebuggingClassWriter.DEBUG_LOCATION_PROPERTY(也就是 cglib.debugLocation)系统属性设置为当前项目的根目录,即可保存 CGLIB 生成的代理类到当前项目根目录下。

设置系统属性配置:

public static void main(String[] args) {
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, System.getProperty("user.dir"));
    Student studentProxy = (Student)CglibProxyFactory.creatCglibProxyObj(Student.class);
    studentProxy.handOut();
}

运行代码:
在这里插入图片描述
生成的动态代理类为:

public class Student$$EnhancerByCGLIB$$723acbd8 extends Student implements Factory {
    
    private boolean CGLIB$BOUND;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static final Method CGLIB$handOut$0$Method;
    private static final MethodProxy CGLIB$handOut$0$Proxy;
    //...

    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("com.zzc.proxy.cglib.Student$$EnhancerByCGLIB$$723acbd8");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$handOut$0$Method = ReflectUtils.findMethods(new String[]{"handOut", "()V"}, (var1 = Class.forName("com.zzc.proxy.cglib.Student")).getDeclaredMethods())[0];
        CGLIB$handOut$0$Proxy = MethodProxy.create(var1, var0, "()V", "handOut", "CGLIB$handOut$0");
        //...
    }

    final void CGLIB$handOut$0() {
        super.handOut();
    }

    public final void handOut() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$handOut$0$Method, CGLIB$emptyArgs, CGLIB$handOut$0$Proxy);
        } else {
            super.handOut();
        }
    }
    
	//...

    static {
        CGLIB$STATICHOOK1();
    }
}

说明:

  1. 生成的动态代理类继承了父类 Student,并且实现了接口 Factory
  2. 动态代理类持有 MethodInterceptor
  3. 动态代理类会重写父类 Student 的非 final、private 方法;也会构建自己的方法(cglib 方法),构建方式:CGLIB”+“$父类方法名$
  4. cglib 方法的方法体:super.方法名,直接调用父类;重写方法:它会调用拦截器中的 intercept() 方法
  5. methodProxy.invokeSuper() 方法会调用动态代理类中的 cglib 方法;methodProxy.invoke() 方法会调用动态代理类中的重写方法

CGLIB 动态代理原理:外界调用了方法后(studentProxy.handOut();),由于父类 Student 被子类(动态代理类)给继承了(已经重写了 handOut()),所以,会调用动态代理类中的 handOut() 方法。而在这个重写的方法中,又会去调用 MethodInterceptor#intercept() 方法。在这个方法中,功能增强后,再去调用动态代理中的 cglib 方法,而此方法又会去调用父类中的方法。

4. JDK 动态代理和 CGLIB 动态代理比较

4.1 区别

总结一下两者的区别吧:

  1. JDK 动态代理基于接口,CGLIB 动态代理基于类。因为 JDK 动态代理生成的代理类需要继承 java.lang.reflect.Proxy,所以,只能基于接口;CGLIB 动态代理是根据类创建此类的子类,所以,此类不能被 final 修饰
  2. JDK 和 CGLIB 动态代理都是在运行期生成字节码。而 JDK 是直接写 Class 字节码;而 CGLIB 使用 ASM 框架写 Class 字节码(不鼓励直接使用ASM,因为它要求你必须对 JVM 内部结构包括 class 文件的格式和指令集都很熟悉)
  3. JDK 通过反射调用方法,CGLIB 通过 FastClass 机制(下一篇再将)直接调用方法。所以,CGLIB 执行的效率较高
  4. JDK 动态代理是利用反射机制生成一个实现代理接口的类(这个类看不见摸不着,在 jvm 内存中有这个类),在调用具体方法前调用 InvokeHandler来处理。核心是实现 InvocationHandler接口,使用 invoke()方法进行面向切面的处理,调用相应的通知;CGLIB 动态代理是利用 asm 开源包,对代理对象类的 class 文件加载进来,通过修改其字节码生成子类来处理。核心是实现 MethodInterceptor 接口,使用 intercept() 方法进行面向切面的处理,调用相应的通知。

4.2 优缺点

劣势:

  1. JDK:JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理
  2. CGLIB:CGLIB 的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对 final 修饰的类进行代理

优势:

  1. JDK:最小化依赖关系,减少依赖意味着简化开发和维护,JDK本身的支持,可能比 cglib 更加可靠
  2. JDK:平滑进行JDK版本升级,而字节码类库通常需要进行更新以保证在新版Java 上能够使用。代码实现简单
  3. CGLIB:从某种角度看,限定调用者实现接口是有些侵入性的实践,类似cglib动态代理就没有这种限制。只操作我们关心的类,而不必为其他相关类增加工作量。另外高性能。

5. 动态代理在 Spring 中的应用

Spring 应用:

  1. 如果目标对象实现了接口,默认情况下 Spring 会采用 JDK 的动态代理实现 AOP
  2. 如果目标对象实现了接口,Spring 也可以强制使用 CGLIB 实现 AOP
  3. 如果目标对象没有实现接口,必须采用 CGLIB 实现动态代理,当然 Spring 可以在 JDK 动态代理和 CGLIB 动态代理之间转换
CGLIB(Code Generation Library)详解 什么是CGLIB CGLIB是一个强大的、高性能的代码生成库。其被广泛应用于AOP框架(Spring、dynaop)中,用以提供方法拦截操作。Hibernate作为一个比较受欢迎的ORM框架,同样使用CGLIB来代理单端(多对一和一对一)关联(延迟提取集合使用的另一种机制)。CGLIB作为一个开源项目,其代码托管在github,地址为:https://github.com/cglib/cglib为什么 阅读详情

相关推荐

cglib 动态代理原理详解

cglib 动态代理详解 我们都知道jdk的动态代理内部调用切面无效的问题,而cglib则不会出现这种情况,这是为什么?cglib就一定不会出现内部调用切面无效的问题吗?cglib针对每一个类只创建了一个代理类吗?为什么cglib的效率要比jdk的动态代理低呢? 首先我们看一下通常我们是如何使用cglib增强一个类的 public class Main { static class Test{ public void test(){ System.out.pr

u012094957的专栏 1269

【深度思考】聊聊CGLIB动态代理原理

聊聊CGLIB动态代理原理。

申城异乡人 2787

深入理解动态代理:JDK动态代理与CGLIB动态代理

动态代理是一种在运行时创建代理对象的技术,通过代理对象来控制对原对象的访问,能够在不修改原对象的情况下添加额外的功能。JDK动态代理:基于Java反射机制,只能代理实现了接口的类。CGLIB动态代理:基于字节码生成技术,可以代理没有实现接口的类。// 抽象主题接口动态代理在Java中提供了一种灵活而强大的机制,能够在运行时为目标对象添加额外的功能。JDK动态代理和CGLIB动态代理各有优势和适用场景,开发者可以根据具体需求选择合适的代理机制。希望这篇文章对你理解动态代理有所帮助。

捕风捉你 · 星桥API接入与大模型实战 3149

CGLIB动态代理详解分析

CGLIB是强大的、高性能的代码生成库,被广泛应用于AOP框架,它底层使用ASM来操作字节码生成新的类,为对象引入间接级别,以控制对象的访问。CGLIB相比于JDK动态代理更加强大,JDK动态代理只能对接口进行代理,而CGLIB既可以代理普通类,也能够代理接口。

weixin_43397326的博客 6586

机械臂算法设计MATLAB|运动学动力学|轨迹规划|路径规划|Simulink

RRT为最常用的路径规划算法,还有其变种(RRT*,RRT-connect等)。RRT是一种多维空间中高效的规划方法。它以一个初始点作为根节点,通过随机采样增加叶子节点的方式,生成一个随机扩展树。随机扩展树不断增长,直到到达目的位置。**Step1:**构建多维状态空间(joint space),**Step2:**构建joint space的障碍检测算法**Step3:**在joint space应用RRT。

qq_35997213的博客 4471

在LangChain中使用DashVector进行高效向量检索

DashVector为需要处理高维向量数据的开发者提供了一种便捷且高效的解决方案。通过将其集成到LangChain生态系统中,您可以轻松实现复杂的语义搜索和数据分析功能。DashVector官方文档LangChain GitHub仓库有关DashVector的详细notebook示例。

sjufgwgfhoia的博客 449

【Spring】Spring AOP底层原理:JDK动态代理和CGLIB动态代理

Spring AOP 的实现原理是基于动态代理和字节码操作的。而动态代理是基于反射机制的。 在编译时, Spring 会使用 AspectJ 编译器将切面代码编译成字节码文件。在运行时, Spring 会使用 Java 动态代理或 CGLIB 代理生成代理类,这些代理类会在目标对象方法执行前后插入切面代码,从而实现AOP的功能。

m0_65277261的博客 3707

Minecraft Forge模组开发入门:从环境搭建到事件监听实战

事件驱动编程是一种基于事件和事件监听器的软件架构模式,其核心原理是通过事件总线实现组件间的松耦合通信。在游戏开发领域,这种模式能够有效处理玩家交互、状态变更等异步操作,具有高度的灵活性和可扩展性。Java作为面向对象编程语言,通过注解和反射机制为事件驱动提供了天然支持。Minecraft模组开发正是事件驱动编程的典型应用场景,开发者可以利用Forge框架提供的事件总线监听游戏内各种行为。本文以Minecraft Forge模组开发为例,详细讲解如何通过Gradle构建工具搭建开发环境,并实现自定义方块注册和

culi3182的博客 391

CGLib动态代理原理

CGLib动态代理原理 CGLib动态代理是代理类去继承目标类,然后重写其中目标类的方法啊,这样也可以保证代理类拥有目标类的同名方法; 看一下CGLib的基本结构,下图所示,代理类去继承目标类,每次调用代理类的方法都会被方法拦截器拦截,在拦截器中才是调用目标类的该方法的逻辑,结构还是一目了然的; 1.CGLib的基本使用 使用一下CGLib,在JDK动态代理中提供一个Proxy类来创建代理类,而在CGLib动态代理中也提供了一个类似的类Enhancer; 使用的CGLib版本是2.2.2,我是随便找的,不

坚定目标,超越自我 5097

从零搭建《火影忍者》手游服务端:Linux环境部署与全流程实战

游戏服务器后端开发是构建大型多人在线体验的核心技术,其原理涉及高并发网络通信、分布式系统架构与数据一致性保障。在技术价值上,一套稳定高效的服务端不仅能支撑海量玩家实时交互,更是游戏业务逻辑、经济系统和安全防线的基石。典型的应用场景包括MMORPG、回合制卡牌、SLG等中重度手游。本文以《火影忍者》IP的横版卡牌回合制手游为例,聚焦于**手工服务端**的完整搭建过程,详细拆解从Linux系统初始化、MySQL与**Redis**缓存部署、核心服务编译、到代理后台联调的全链路实践,为开发者深入理解游戏后端架构提

weixin_30800615的博客 328

Sparse4Dv3 代码复现

打包数据集的元信息和标签,并生成所需的.pkl文件。最后还输出了很多跟踪相关的东西...然后通过K-means生成锚点。编译可变形聚合CUDA算子。安装motmetrics。

m0_60857098的博客 4480

CGLIB 动态代理及其原理分析

一、简介   CGLIB,即 Code Generation Library,是一个强大的、高性能的代码生成库。它可以在运行期扩展 Java 类与实现 Java 接口(JDK 动态代理只能用于接口),它被许多 AOP 框架广泛地使用,如为 Spring AOP 提供方法的 interception(拦截),被 Hibernate 用来代理单端(多对一和一对一)关联(延迟提取集合使用的另一种机制)。本文使用的 CGLIB 依赖如下: <dependency> <groupId>

weixin_41427129的博客 6204

AIGC实战指南:从提示词到工作流,掌握AI内容生成核心技能

人工智能生成内容(AIGC)作为当前AI技术的重要应用领域,其核心原理基于大语言模型(LLM)对海量数据的学习与模式识别。这项技术的价值在于将复杂的创作过程自动化,显著提升内容生产效率与创意实现的多样性。在实际应用中,AIGC已广泛渗透至文本创作、图像设计、音频合成及视频生成等多个场景,成为数字内容生产的重要工具。要高效运用AIGC,关键在于掌握提示词工程与模型微调等核心技能。例如,通过结构化提示词设计,可以精确引导模型生成符合预期的专业周报;而选择合适的微调模型,则能大幅提升图像生成的风格控制力与输出质量

weixin_26808439的博客 368

CGLIB动态代理实现原理

一、CGLIB介绍 CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象)字节码的动态生成。 CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP为他...

AN_ERA的博客 1111

Unity Animancer插件(一)基本使用

Animancer是什么?资源商店主页我们来通过Animancer实现一个最基本的动画播放效果。首先创建一个脚本,编写如下代码 很容易理解,就是在时播放一个指定的动画片段。接下来为角色添加、和刚刚编写的,并为字段赋值 接下来运行游戏就可以看到效果了 此时角色身上的组件可以看到当前动画的各项参数 下面我们来实现通过按键控制角色在于之间转换。新创建一个脚本。在代码中监听Y轴上的输入。然后根据监听到的数值判断角色状态,并播放相应的动画 给对应字段赋值后,启动游戏看下效果 下面来实现一个开枪效果。在默认状态下,角色

夜槿笙歌的博客 1万+

Buck电源设计常见的一些问题(一)半桥栅极驱动芯片共性失效问题

半桥驱动芯片主要用在器件可应用于电信,数据通信,便携式存储或更低电压系统中的电源转换器,半桥、全桥、推挽、同步降压,正激变换器和同步整流器等方面。当然难免会遇到不少问题。基本上我们在产品开发的过程中都遇到过栅极驱动芯片坏掉的情况,所以找了一些资料,学习学习。也查找查找原因。

小幽余生不加糖 2361

动态代理:Cglib原理讲解

Cglib动态代理不需要被代理类实现接口,根据原理我们知道生成的代理类是继承了被代理类,而且其方法调用方法是使用FastClass,这与JDK动态代理的反射有比较大的区别。JDK代理使用的是反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。CGLIB代理使用字节码处理框架ASM,对代理对象类的class文件加载进来,通过修改字节码生成子类。JDK创建代理对象效率较高,执行效率较低;CGLIB创建代理对象效率较低,执行效率高。

猪大肠的博客 1408

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【Spring基础】CGLIB动态代理实现原理

前言 Github:https://github.com/yihonglei/thinking-in-spring 一 CGLIB介绍 CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库, 它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象)...

yhl_jxy的博客 8万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

CGLIB动态代理底层实现原理

一、前言 最近在探究Spring AOP的性能,发现最后是绕不开JDK动态代理和CGLIB动态代理这两个点。笔者心里大致有这么个概念:对于动态代理来说,CGLIB性能要好于JDK。也知道CGLIB是利用ASM技术基于继承子类实现动态代理,JDK是基于实现接口实现动态代理,但是对于底层实现还是比较模糊。今天就彻底整明白CGLIB动态代理的底层实现。二、前置准备(一)测试代码CGLIB核心的几个概念...

wajueji的博客 933

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

cglib动态代理实现原理_全面解析动态代理 JDK Proxy 及 CGLib 原理

@本文阅读大概需要6分钟1 什么是代理 代理的目标是为某一个对象提供一个代理,并由代理对象来控制对原对象的访问。依据代理类的创建时间,分为静态代理和动态代理。静态代理是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前已经确定好。动态代理是程序在运行期间动态构建代理对象和动态调用代理方法的一种机制。在程序运行时,通过反射机制动态创建而成。简单地说,代理是用来在被代理对...

weixin_32716541的博客 1455

Cglib动态代理实现原理

Cglib动态代理实现原理: 我们先通过一个demo看一下Cglib是如何实现动态代理的。 首先定义个服务类,有两个方法并且其中一个方法用final来修饰。 public class PersonService { public PersonService() { System.out.println("PersonService构造"); } //该方法不...

黄亚的博客 348

CGLIB动态代理的实现及原理

CGLIB介绍与原理(部分节选自网络)一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中...

留下你的观点 601

JDK动态代理 和CGLib动态代理实现原理和两者的区别

JDK动态代理和CGLib动态代理

zeng2813的博客 1089

jdk与cglib动态代理及原理

Spring的AOP在运行时多以jdk及cglib动态代理来实现

KEEP CODING 1026
上一篇: 【动态代理】JDK 动态代理的使用及原理
下一篇: 【SpringBoot】SpringBoot 中的 切面 AOP + 自定义注解
sco5282
博客等级 码龄5年 844粉丝 154原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值