从动态代理角度简单理解Spring AOP

1. 概述

动态代理 是指在运行时,动态地创建目标类的代理对象,并对其中特定的方法进行拦截或增强的技术。这种技术主要用于在不修改目标类代码的情况下,增强目标类的功能。 
在Java中,动态代理主要基于Java的反射机制和接口来实现。当一个类实现了某个接口,并且需要在不修改这个类代码的前提下增加一些新的方法或者对原有方法进行一些处理(比如添加日志、事务管理、权限校验等),就可以使用动态代理来实现。即它可以无侵入式的修改代码

2. 讲故事

为了方便理解,我这里举一个生活中的故事吧,前不久报名了微软云的认证考试,报名之后前往考点,我才发现这个考点其实根本就不是微软公司亲自设立的,而是有其他公司代理的,因为微软虽大,但是不可能在世界每一个城市都亲自设立办公处或者说是认证考点吧。这种情况下微软就需要请其他公司代理。帮他管理考试过程。那么微软和代理公司在这个过程中分别做了什么呢?
首先是代理公司:

  • 代理公司需要提供考点
  • 当考生到了考点后,大代理公司的工作人员,需要对参考的考生进行检查确认考生没有夹带或使用作弊工具
  • 代理公司需要查询考生证件,确包是考生本人,而不是代考
  • 代理公司需要对考生全身照和寸照,用于给微软公司证明考生无夹带,以及将寸照传入电子证书上。
  • 代理公司需要提供考试电脑,并帮助考试宣讲考试步骤,考试过程摄像。教考试如何远程获取使用微软考题。
  • 代理公司维持考场秩序
  • 如果考生考过了,代理公司需要打印微软发送的证书,发给考生。

而微软做了什么呢:

  • 管理考生报名
  • 网上收取考生考试费用
  • 考试时远程提供题库
  • 远程发送证书

通过上面我们可以看到,代理给微软节省了很多成本,也省了很多事,而代理公司通过这个过程也可以做一个兼职赚了一笔外快。是一个双赢的局面。生活中这样的例子有很多。
所以我们程序里面的动态代理,可以有很多类似的效果,为我们程序员减少重复代码,提高扩展性等都很有用处。

3.动态代理的实现步骤如下:

  1. 定义接口:首先定义一个接口,这个接口定义了目标类需要实现的方法。
    package com.mycompany.proxyreflection2;public interface ExamServer {String examAz900();String examAz700();
    }
    

  2. 实现目标类:创建一个类实现上述接口,这个类就是目标类。
    package com.mycompany.proxyreflection2;public class TargetCompanyExamServerImpl implements ExamServer {@Overridepublic String examAz900() {return "This is microsoft, wlc exam azure 900, transfer the question bank to proxy";}@Overridepublic String examAz700() {return "This is microsoft, wlc exam azure 700, transfer the question bank to proxy";}
    }
    
  3. 创建InvocationHandler:创建一个实现了InvocationHandler接口的类,这个类将负责拦截并处理对目标类方法的调用。
    package com.mycompany.proxyreflection2;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;public class ProxyCompanyInvocationHandler implements InvocationHandler {private final Object target; // 目标对象 举例中的微软对象public ProxyCompanyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在调用目标方法之前执行一些操作(例如日志记录)System.out.println("代理公司需要提供考点");System.out.println("当考生到了考点后,大代理公司的工作人员,需要对参考的考生进行检查确认考生没有夹带或使用作弊工具");System.out.println("代理公司需要查询考生证件,确包是考生本人,而不是代考");System.out.println("代理公司需要对考生全身照和寸照,用于给微软公司证明考生无夹带,以及、便将寸照传入电子证书上。");System.out.println("代理公司需要提供考试电脑,并帮助考试宣讲考试步骤,考试过程摄像。教考试如何远程获取使用微软考题。");// 调用目标对象上的方法, 获取微软考题Object result = method.invoke(target, args);System.out.println(result);// 在调用目标方法之后执行一些操作(例如日志记录)System.out.println("代理公司维持考场秩序");System.out.println("如果考生考过了,代理公司需要打印微软发送的证书,发给考生。");return result;}
    }
    
  4. 创建代理对象:使用Proxy类的newProxyInstance方法,传入目标类的类加载器、目标类实现的接口列表以及InvocationHandler实例,来创建代理对象。
    package com.mycompany.proxyreflection2;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;public class ProxyCompany {public static <T> T createProxy(T target) {// 获取目标对象的类加载器和接口类型ClassLoader classLoader = target.getClass().getClassLoader();Class<?>[] interfaces = target.getClass().getInterfaces();// 创建一个 InvocationHandler 实例InvocationHandler handler = new ProxyCompanyInvocationHandler(target);// 使用 Proxy 类的静态方法 newProxyInstance 创建代理对象T proxy = (T) Proxy.newProxyInstance(classLoader, interfaces, handler);return proxy;}
    }
    
  5. 调用方法:通过代理对象调用目标类的方法时,会首先被InvocationHandler的invoke方法拦截,可以在这个方法中添加额外的处理逻辑,然后再调用目标类的方法。
    package com.mycompany.proxyreflection2;public class ExamApi {public static void main(String[] args) {// 创建一个 ExamServer 的实现类实例ExamServer myService = new TargetCompanyExamServerImpl();// 使用 ProxyFactory 创建一个 ExamServer 的代理实例ExamServer proxyService = ProxyCompany.createProxy(myService);// 调用代理实例上的方法System.out.println("-----------------Start proxy exam Az 700----------------");proxyService.examAz700();System.out.println("-----------------Start proxy exam Az 900----------------");proxyService.examAz900();}
    }
    

    运行结果:

-----------------Start proxy exam Az 700----------------
代理公司需要提供考点
当考生到了考点后,大代理公司的工作人员,需要对参考的考生进行检查确认考生没有夹带或使用作弊工具
代理公司需要查询考生证件,确包是考生本人,而不是代考
代理公司需要对考生全身照和寸照,用于给微软公司证明考生无夹带,以及、便将寸照传入电子证书上。
代理公司需要提供考试电脑,并帮助考试宣讲考试步骤,考试过程摄像。教考试如何远程获取使用微软考题。
This is microsoft, wlc exam azure 700, transfer the question bank to proxy
代理公司维持考场秩序
如果考生考过了,代理公司需要打印微软发送的证书,发给考生。
-----------------Start proxy exam Az 900----------------
代理公司需要提供考点
当考生到了考点后,大代理公司的工作人员,需要对参考的考生进行检查确认考生没有夹带或使用作弊工具
代理公司需要查询考生证件,确包是考生本人,而不是代考
代理公司需要对考生全身照和寸照,用于给微软公司证明考生无夹带,以及、便将寸照传入电子证书上。
代理公司需要提供考试电脑,并帮助考试宣讲考试步骤,考试过程摄像。教考试如何远程获取使用微软考题。
This is microsoft, wlc exam azure 900, transfer the question bank to proxy
代理公司维持考场秩序
如果考生考过了,代理公司需要打印微软发送的证书,发给考生。 

这种方式的优点是可以在不修改目标类代码的情况下增加新的功能,提高了系统的灵活性和可扩展性。但是,由于Java的动态代理是基于接口的,所以目标类必须实现一个或多个接口,否则无法使用动态代理。

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

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

相关文章

gdc2024:Raytracing in Snowdrop技术实现与性能优化策略

在今年的GDC&#xff08;游戏开发者大会&#xff09;的Advanced Graphics Summit上&#xff0c;关于Snowdrop引擎中光线追踪技术的讨论引起了广泛关注。 一、光线追踪全局照明的实现细节 屏幕空间追踪&#xff1a; 屏幕空间追踪从相机出发&#xff0c;对屏幕上的每个像素点生成…

DDL—表—数据类型—字符串类型相关语法

&#xff08;1&#xff09;表格可视化 普通字符串 类型大小描述CHAR0~255 bytes定长字符串&#xff0c;其表示即使你存储一个字符&#xff0c;它也会占用你括号里个数的字符的空间&#xff0c;因为未占用的字符的其它空间会用空格进行补位。需要再后面跟一个参数&#xff1a;…

harmony 鸿蒙ArkUI动画/交互事件开发常见问题(ArkTS)

ArkUI动画/交互事件开发常见问题(ArkTS) 焦点事件onBlur/onFocus回调无法触发(API 9) 问题现象 焦点事件onBlur/onFocus回调无法触发 解决措施 焦点事件默认情况下需要外接键盘的Tab键&#xff0c;或方向键触发&#xff0c;点击触发焦点事件需要添加焦点控制属性focusOnTo…

Linux 监控USB硬盘插拔事件并自动挂载和卸载

定义udev规则来监控USB插拔事件。 一、在/etc/udev/rules.d目录下随意创建一个规则文件&#xff0c;例&#xff1a;99-usb-mount.rules KERNEL"sd[b-z]?",SUBSYSTEM"block",RUN"/usr/local/src/mountusb.sh %k $env{ACTION}"二、创建 /usr/lo…

基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究

技术背景 2014年4月8日起&#xff0c;美国微软公司停止了对Windows XP SP3操作系统提供服务支持&#xff0c;这引起了社会和广大用户的广泛关注和对信息安全的担忧。而2020年对Windows7服务支持的终止再一次推动了国产系统的发展。工信部对此表示&#xff0c;将继续加大力度&a…

C++ 红黑树

目录 1.红黑树的概念 2.红黑树的性质 3.红黑树节点的定义 4.红黑树的插入操作 5.数据测试 1.红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个…

C++基础与深度解析 | 泛型算法 | bind | Lambda表达式

文章目录 一、泛型算法1.泛型算法的分类2.迭代器分类 二、bind与lambda表达式1.bind2.lambda表达式 三、泛型算法的改进--ranges(c20) 一、泛型算法 C中的泛型算法是标准模板库&#xff08;STL&#xff09;的一部分&#xff08;这里重点讨论 C 标准库中定义的算法&#xff0c;而…

【vue-cli搭建vue项目的过程2.x】

vue-cli搭建vue项目 vue-cli搭建vue项目安装node安装vue-cli脚手架并创建项目安装 Ant Design Vue或element-ui(笔者使用Ant-design-vue组件&#xff0c;并全局引入)开发安装三方库包1、Package.json文件---引入如下package.json文件执行npm i或npm install命令即可下载如下依赖…

数据结构~~链式二叉树

目录 一、基本概念 链式存储概念 二、链式二叉树的结构 链式二叉树结构 构建链式二叉树 二叉树的遍历 二叉树节点和高度等 二叉树销毁 三、链式二叉树的练习 相同的树 对称二叉树 另外一颗子树 二叉树前序遍历 二叉树遍历 四、完整代码 Tree.h Tree.c 五、总结 一…

Linux服务升级:Predixy 升级代理 Redis-cluster 集群

目录 一、实验 1.环境 2. 启动Redis服务 3.Predixy 升级代理 Redis-cluster 集群 二、问题 1. Predixy进行set操作报错 2.如何创建脚本启动predixy 3.Redis代理对比 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统版本节点软件IP备注CentOS7.9Redis…

Springboot开发 -- Postman 调试类型详解

引言 在 Spring Boot 应用开发过程中&#xff0c;接口测试是必不可少的一环。Postman 作为一款强大的 API 开发和测试工具&#xff0c;可以帮助开发者轻松构建、测试和管理 HTTP 请求。本文将为大家介绍如何在 Spring Boot 开发中使用 Postman 进行接口测试。 一、准备工作 安…

C/C++|malloc分配内存详解

看本节前&#xff0c;希望读者有linux内存分布的基本概念&#xff0c;可以阅读这篇文章&#xff1a; 进程虚拟地址空间和函数调用栈 在本节中希望读者可以一口气阅读完所有内容。 本博客内容全部来自小林coding&#xff1a;malloc 是如何分配内存的&#xff1f; 这里仅为笔记记…

Python-图片旋转360,保存对应图片

#Author &#xff1a;susocool #Creattime:2024/5/25 #FileName:turn360 #Description: 会旋转指定的图像文件360度&#xff0c;并将每个旋转后的图像保存到指定目录&#xff0c;文件名以旋转角度命名。 from PIL import Imagedef rotate_and_save(image_path, output_dir) :# …

Linux/Ubuntu 中安装 ZeroTier,实现内网穿透,2分钟搞定

相信很多人都有远程连接家中设备的需求&#xff0c;如远程连接家中的NAS、Windows等服务&#xff0c;所以会涉及到一个内网穿透工具的使用&#xff0c;如果没有公网IP的情况下&#xff0c;推荐大家使用ZeroTier&#xff0c;这是一款强大的内网穿透工具。 mac和windows版的操作…

Nginx-狂神说

Nginx概述 公司产品出现瓶颈&#xff1f; 我们公司项目刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发的情况下&#xff0c;一个jar包启动应用就够了&#xff0c;然后内部tomcat返回内容给用户。 但是慢慢的&#xff0c;使用我们平台…

HTTP 各版本差异

http1.0 它的特点是每次请球和响应完毕后都会销毁TCP 连接。同时规走前一个响应完成后才发送下一个请求。这样做有两个问题&#xff1a; 无法复用连接了。 每次请求都要创建新的TCP连接&#xff0c;完成三次握手和四次挥手。网络利用率低 队头阻塞 如果前一个请求被某种原因阻…

K8S认证|CKA题库+答案| 13. sidecar 代理容器日志

目录 13、使用 sidecar 代理容器日志 CKA v1.29.0模拟系统免费下载试用&#xff1a; 题目&#xff1a; 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、生成yaml文件 3&#xff09;、官网找模板 4&#xff09;、编辑yaml文件 5&#xff09;、应用yaml…

车载电子电器架构 —— 智能座舱技术

车载电子电器架构 —— 智能座舱技术 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的…

qt multiple definition of 报错解决

qt编译报了很多错&#xff0c; multiple definition of xxx 原来一维设计文件ui 的问题 后来发现是pro中头文件和cpp文件重写了&#xff0c;导致重复编译报的错 解决方法&#xff1a;把重复的头文件和cpp文件删了就可以了。

如何解决0.1+0.2!=0.3的问题

var x 0.1; var y 0.2; var z x y // z 的结果为 0.30000000000000004 if (z 0.3) // 返回 false 可以用整数的乘除法来解决 var z (x * 10 y * 10) / 10; // z 的结果为 0.3