快来,一起复习一下JDK动态代理和CGLib动态代理的区别

news2024/12/22 16:32:24

背景

工作也有四年了,基础的东西许久不看有些遗忘。一起来复习一下吧

JDK动态代理和CGLib的区别

JDK动态代理主要是针对类实现了某个接口,AOP则会使用JDK动态代理。它基于反射的机制实现,生成一个实现同样接口的一个代理类,然后通过重写方法的方式,实现对代码的增强。

而如果某个类没有实现接口,AOP则会使用CGLIB代理。它的底层原理是基于asm第三方框架,通过修改字节码生成成一个子类,然后重写父类的方法,实现对代码的增强。

JDK创建代理对象效率较高,执行效率较低;
CGLIB创建代理对象效率较低,执行效率高。

JDK动态代理机制是委托机制,只能对实现接口的类生成代理,通过反射动态实现接口类;
CGLIB则使用的继承机制,针对类实现代理,被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,因为是继承机制,不能代理final修饰的类。

代码实现区别

  • JDK动态代理实现方式

接口层

package com.springboot.demo.base.service;

public interface UserService {
    /**
     * 新增用户
     * @param name
     */
    void addUser(String name);
}

实现类

package com.springboot.demo.base.service;

public class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        System.out.println("yes i am add one user");
    }
}

代理类

package com.springboot.demo.base.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class UserProxy implements InvocationHandler {
    private Object target;

    public UserProxy(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


        Object result = method.invoke(target, args);

        System.out.println("记录日志");
        return result;
    }
}

测试类

 public static void main(String[] args) {
        //jdk
            UserServiceImpl impl = new UserServiceImpl();
            UserProxy userProxy = new UserProxy(impl);
            UserService userService = (UserService) Proxy.newProxyInstance(impl.getClass().getClassLoader(),impl.getClass().getInterfaces(),userProxy);
            userService.addUser("aaaaa");
    }

执行结果

在这里插入图片描述

  • CDLib动态代理实现方式

实现类和接口类与JDK一致,这里就不重复贴了。

不一样的是CGLib还依赖一个包

<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.5</version>
		</dependency>

代理类

package com.springboot.demo.base.utils;

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 UserCGLib implements MethodInterceptor {
    private Object target;

    public UserCGLib() {
    }

    public UserCGLib(Object target) {
        this.target = target;
    }

    //返回一个代理对象:    是 target对象的代理对象
    public Object getProxyInstance() {
        //1. 创建一个工具类
        Enhancer enhancer = new Enhancer();
        //2. 设置父类
        enhancer.setSuperclass(target.getClass());
        //3. 设置回调函数
        enhancer.setCallback(this);
        //4. 创建子类对象,即代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("增强开始~~~");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("增强结束~~~");
        return result;
    }


}

测试类

 public static void main(String[] args) {
   
            //cglib

        UserCGLib serviceCGlib = new UserCGLib(new UserServiceImpl());
        UserServiceImpl userServic1e = (UserServiceImpl)serviceCGlib.getProxyInstance();
        userServic1e.addUser("add");
        System.out.println();
    }

执行结果

在这里插入图片描述

总结

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理
2、如果目标对象实现了接口,也可以强制使用CGLIB
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

如果需要强制使用CGLIB来实现AOP,需要配置spring.aop.proxy-target-class=true或@EnableAspectJAutoProxy(proxyTargetClass = true

参考
https://zhuanlan.zhihu.com/p/440452860
https://blog.csdn.net/qq_59527118/article/details/127386305

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MongoDB 学习

文章目录 前言1、MongoDB 的优势是什么2、部署2.1、Windows 系统中的安装启动2.2、Shell连接&#xff08;mongo命令&#xff09;2.3、Compass-图形化界面客户端2.4、Linux系统中的安装启动和连接 3、基本常用命令3.1、选择和创建数据库3.2、数据库删除3.3、集合操作3.3.1、集合…

HEVC预测编码介绍

介绍 ● 一幅图像内邻近像素之间有着较强的空间相关性&#xff0c;相邻图像之间也有很强的时间相关性&#xff1b; ● 预测编码&#xff08;Prediction Coding&#xff09;是指利用已编码的一个或几个样本值&#xff0c;根据某种模型或者方法&#xff0c;对当前的样本值进行预…

LeetCode572. 另一棵树的子树

题目 leetcode572. 另一棵树的子树 思路 递归解决。 ①递归的大问题化小----判断c是否为a子树可以转换为判断c是否为a左子树的子树或者c是否为a右子树的子树。 ②递归的结束条件-----如果两颗树相同&#xff0c;返回true&#xff1b;两棵树为空&#xff0c;返回true&#xff…

【十三】设计模式~~~行为型模式~~~中介者模式(Java)

中介者模式-Mediator Pattern【学习难度&#xff1a;★★★☆☆&#xff0c;使用频率&#xff1a;★★☆☆☆】 2.1. 模式动机 在用户与用户直接聊天的设计方案中&#xff0c;用户对象之间存在很强的关联性&#xff0c;将导致系统出现如下问题&#xff1a;系统结构复杂&#…

动态规划-硬币排成线

动态规划-硬币排成线 1 描述2 样例2.1 样例 1:2.2 样例 2:2.3 样例 3: 3 算法解题思路及实现3.1 算法解题分析3.1.1 确定状态3.1.2 转移方程3.1.3 初始条件和边界情况3.1.4 计算顺序 3.2 算法实现3.2.1 动态规划常规实现3.2.2 动态规划滚动数组 该题是lintcode的第394题&#x…

第二十一章 开发Productions - ObjectScript Productions - 延迟发送

文章目录 第二十一章 开发Productions - ObjectScript Productions - 延迟发送延迟发送 生成事件日志条目在 ObjectScript 中生成事件日志条目 第二十一章 开发Productions - ObjectScript Productions - 延迟发送 延迟发送 除了同步&#xff08;等待&#xff09;和异步&…

9秒被骗245万元?AI火了,骗子也来了!

生成式AI技术&#xff0c;如GPT-4等强大的语言模型的广泛普及&#xff0c;已经逐步开展应用。这种对未来技术的期待之余&#xff0c;不得不面对AI技术可能被滥用的风险&#xff0c;甚至已经有一些犯罪分子已开始巧妙地利用AI技术进行电信诈骗。 当下最积极学习的除了学生&#…

【高危】Apache bRPC <1.5.0 存在任意代码执行漏洞

漏洞描述 Apache bRPC 是C开发、由百度RPC发展而来的工业级 RPC 框架。 该项目受影响版本存在任意代码执行漏洞&#xff0c;由于server.cpp对于用户输入的pid_file使用wordexp展开。 具备bRPC控制权限的攻击者可在bRPC启动时通过控制pid_file参数注入恶意内容&#xff08;如…

DNS隧道流量分析

1.域名准备 选择哪家的云都没问题&#xff0c;国内云需要实名&#xff0c;不建议使用&#xff0c;这里我选择的TX云&#xff0c;因为之前注册过了&#xff0c;自己拿来做个流量分析不成问题 域名添加解析记录 需要准备自己的vps作为DNS隧道的服务端&#xff0c;且需要添加ns…

.nc文件根据经纬度提取点上数值python

.nc文件根据经纬度提取点上数值python 1、数据集2、代码部分3、完整代码 1、数据集 VOD Climate Archive &#xff08;VODCA&#xff09; 数据由维也纳工业大学提供&#xff08;https://doi.org/ 10.5281/zenodo.2575599&#xff09;。VODCA是一种空间分辨率为0.25的全球每日V…

【十一】设计模式~~~结构型模式~~~代理模式(Java)

【学习难度&#xff1a;★★★☆☆&#xff0c;使用频率&#xff1a;★★★★☆】 6.1. 模式动机 在某些情况下&#xff0c;一个客户不想或者不能直接引用一个对 象&#xff0c;此时可以通过一个称之为“代理”的第三者来实现 间接引用。代理对象可以在客户端和目标对象之间起…

网络流量管理系统

网络监控对于当今的组织至关重要&#xff0c;该过程的一个关键方面是分析网络的正常运行时间、可用性、性能和安全性。随着云和物联网技术越来越多地成为现代 IT 环境的一部分&#xff0c;网络管理员必须更加警惕他们授予访问权限的流量&#xff0c;包括确定谁在使用他们的网络…

【十四】设计模式~~~行为型模式~~~中介者模式(Java)

【学习难度&#xff1a;★★★☆☆&#xff0c;使用频率&#xff1a;★★★★★】 3.1. 模式动机 建立一种对象与对象之间的依赖关系&#xff0c;一个对象发生改变时将自动通知其他对象&#xff0c;其他对象将相应做出反应。在此&#xff0c;发生改变的对象称为观察目标&#…

提高测试效率5大捷径

1、优先级 测试任务和开发任务一样&#xff0c;都需要进行优先级排序。在测试工作中&#xff0c;优先进行级别高的测试任务&#xff0c;这样能够在无法保障测试周期的前提下&#xff0c;也不会对整体开发进度造成较大的影响。 提高测试效率5大捷径 2、重视测试策略 测试策略的基…

零代码,使用 Dify 两分钟接入企业微信

前置准备 企业微信的管理员权限 一个 Dify 的帐号 一个 Laf 云的帐号 &#xff08;可选&#xff09;一个 OpenAI 的 API Key。如果没有&#xff0c;可以使用 Dify 免费提供的 200 次调用机会用于测试。 &#xff08;可选&#xff09;在电脑上新建一个 env.txt 的文件&#…

C++进阶 —— 列表初始化(C++11新特性)

目录 一&#xff0c;列表初始化 二&#xff0c;类列表初始化 三&#xff0c;类模板列表初始化 库模板初始化列表实现 模拟模板初始化列表实现 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称&…

神经网络与机器学习

《神经网络与深度学习》 第一章 绪论1.1 人工智能知识结构预备知识顶会论文常用的深度学习框架研究领域 1.2 如何开发AIS芒果机器学习 1.3 表示学习局部表示和分布式表示 1.4 深度学习&#xff08;Deep Learning) 第一章 绪论 1.1 人工智能 人工智能的一个子领域 神经网络&a…

百度商业AI技术创新大赛火热进行中,携手专家大咖一起创新为更好!

百度商业AI技术创新大赛火热进行中 来自百度、中国人工智能学会 及NVIDIA的专家大咖纷纷送上寄语 希望与充满创新思维的年轻人一起 探讨AI技术的创新应用 挖掘AIGC在商业领域发展的更多可能 开启中国人工智能发展新篇章&#xff01; -戴琼海- 国务院参事 CAAI理事长 …

分布式锁的应用场景与分布式锁实现(三):基于Zookeeper实现分布式锁

分布式锁的应用场景与分布式锁实现&#xff08;二&#xff09;&#xff1a;基于Redis实现分布式锁 基于Zookeeper实现分布式锁 ​ 实现分布式锁目前有三种流行方案&#xff0c;分别为基于数据库、Redis、Zookeeper的方案。这里主要介绍基于zk怎么实现分布式锁。在实现分布式锁…

每日一题——重复的子字符串

每日一题 重复的子字符串 题目链接 注&#xff1a;本题的题解基本建立在KMP算法之上&#xff0c;对KMP算法不太了解的小伙伴可以参考这篇文章KMP算法及其改进图文详解 方法一&#xff1a;移动匹配 我们先来看几个可以由一个字串重复多次构成的主字符串&#xff1a;“aaa”&am…