Spring动态代理详解

一,动态代理

       我发现Spring框架中的动态代理是一种非常强大的机制,它可以在运行时为接口或类创建动态代理,然后通过这些代理在方法调用前后添加额外的行为。在后续Spring的AOP(面向切面编程)支持中扮演了关键角色。

二,应用目的

     Spring动态代理主要用于以下目的:

  1. 事务管理:在方法执行前后自动开始和提交事务。
  2. 安全性:在方法执行前进行权限检查。
  3. 性能监控:在方法执行前后添加日志来监测性能

三,核心组件

  • Proxy:代理是动态创建的类,它在目标类的基础上增加了额外的处理逻辑。当通过代理对象调用方法时,代理会先调用与之相关的拦截器链。
  • InvocationHandler(JDK动态代理):这是实际的拦截逻辑所在,定义了在调用目标方法前后应当执行的操作。每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。(接口中仅有Invoke方法)
  • invoke:处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。

四, invoke(object proxy, method,Object[] args)方法参数

  1. proxy ---- 调用该方法的代理实例
  2. method----所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
  3. args-----包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。

五,例(案例参考租房需求代理)

1.创建动态代理

// 租赁公司用这个类,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {// 被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent = rent;}// 生成代理类public Object getProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);}// 代理类要执行的,方法增强public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 调用代理对象,就是使用真实对象调用!Object result = method.invoke(rent, args);return result;}
}
这段代码定义了一个ProxyInvocationHandler类,实现了Java的InvocationHandler接口,用于创建一个动态代理。这个类中有几个关键部分:
  1. 私有成员变量rent:它是Rent接口的一个实现,代表被代理的对象。
  2. setRent 方法:用于设置代理的目标对象。
  3. getProxy 方法:利用Proxy.newProxyInstance方法生成代理对象。这个方法需要三个参数:类加载器,接口数组(代理类需要实现的接口),以及一个InvocationHandler实例(当前对象this)。
  4. invoke 方法:这是代理实例的方法调用时实际执行的代码。invoke方法可以在调用目标方法前后添加自定义逻辑,本例中只是简单地调用了目标对象的相应方法。

2.定义租房接口

//租房
public interface Rent {public void rent();
}

3.定义房东租房任务

//模拟房东出租房屋
public class Host implements Rent{public void rent(){system.out.println("房东要出租房屋")}
}

4.实现动态代理

package com.kuang.demo03;public class Client {public static void main(String[] args) {// 生成被代理对象Host host = new Host();// 代理角色:现在没有ProxyInvocationHandler pih = new ProxyInvocationHandler();// 通过调用程序处理角色来处理我们要调用的接口对象---也就是可以调用host里面的任务pih.setRent(host);Rent proxy = (Rent) pih.getProxy();proxy.rent();}
}
代码定义了一个客户端类Client,演示如何使用动态代理。这里的重点在于如何创建代理对象并通过它来调用方法:
  1. Host实例化:首先创建了一个Host对象,Host是Rent接口的实现类,代表租赁服务的具体实现。
  2. ProxyInvocationHandler实例化:接着创建一个ProxyInvocationHandler的实例。这个类是用来定义代理逻辑的处理器。
  3. 设置代理的目标对象:通过pih.setRent(host)将host对象设置为代理的目标对象。
  4. 获取代理对象:通过pih.getProxy();获取代理对象。这一步是通过代理处理器和Java的Proxy类动态生成一个符合Rent接口的代理对象。
  5. 通过代理对象调用方法:最后通过代理对象调用Rent()方法。如果ProxyInvocationHandler的invoke方法可以添加特定逻辑(如打印日志、权限校验等),它们会在这一步执行。

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

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

相关文章

农林企业资质提升策略:聚焦农业综合生态乙级认证

1. 深入了解资质要求 首要任务是全面细致地研究乙级资质的最新标准和要求,包括企业规模、技术人员配置、过往项目经验、财务状况、管理体系等具体指标。 2. 专业团队构建 强化技术团队,确保拥有一支包含注册农业工程师、生态学专家、环境工程师、农业…

vue 自定义组件 实现跟使用

新建文件组件 选择器作用 ~ 波浪线这个是选择 li 后面的所有 a标签 调用 到使用的文件下引入 使用 效果

每日算法-插值查找

1.概念 插值查找是一种改良版的二分查找,其优势在于,对于较为均匀分布的有序数列,能够更快地使得mid中间游标快速接近目标值. 2.计算公式 中间游标计算公式. 公式说明: 公式的主要思路是,以第一次定位mid中间游标为例, 在接近平均分配的情况下,左右游标之间的差值表示总计供…

Animate软件基础:从单个图层复制帧

在使用Animate软件制作内容时,有时会需要复制制作好的部分动画,到新的场景中,或者从一个制作文件中复制内容到另一个制作文件,这就需要复制帧的操作,这里讲一下从单个图层复制帧的方法。 在图层中选择一组帧。要选择整…

React@16.x(44)路由v5.x(9)源码(1)- path-to-regexp

目录 1,作用2,实现获取 match 对象2.1,match 对象的内容2.2,注意点2.3,实现 1,作用 之前在介绍 2.3 match 对象 时,提到了 react-router 使用第3方库 path-to-regexp 来匹配路径正则。 我们也…

新能源汽车 LabCar 测试系统方案(二)

什么是LabCar测试 LabCar测试目标是进行整车黄板台架功能测试,用于整车开发和测试阶段,满足设计人员和测试人员的试验需求,以验证整车性能,减少开发工作量。系统主要用于测试静态及动态工况下的纯电动汽车的各项功能实现情况。 …

git 用户名密码Clone代码

#密码中包含,则使用%40代表 cd /disk03/wwwroot/GitDemo/BuildTemp && git clone -b dev --single-branch http://root:test%40123192.168.31.104/root/SaaS.Auto.Api.git git pull origin dev 今天使用LibGit2Sharp在Linux上Clone代码时报错,因…

【计算机网络】HTTP——基于HTTP的功能追加协议(个人笔记)

学习日期:2024.6.29 内容摘要:基于HTTP的功能追加协议和HTTP/2.0 HTTP的瓶颈与各功能追加协议 需求的产生 在Facebook、推特、微博等平台,每分每秒都会有人更新内容,我们作为用户当然希望时刻都能收到最新的消息,为…

laravel Dcat Admin 入门应用(三)Grid 之 Column

Dcat Admin 是一个基于 Laravel-admin 二次开发而成的后台构建工具,只需很少的代码即可构建出一个功能完善的高颜值后台系统。支持页面一键生成 CURD 代码,内置丰富的后台常用组件,开箱即用,让开发者告别冗杂的 HTML 代码。 larav…

如何在Vue3项目中引入TypeScript

在这篇文章中,我们将一步步指导你如何在Vue3项目中引入TypeScript。TypeScript是一种强类型的JavaScript超集,可以帮助我们在编写代码时避免许多错误,提高代码的可维护性。下面是具体的实现过程: 第一步:初始化Vue3项目…

Python | Leetcode Python题解之第188题买卖股票的最佳时机IV

题目: 题解: class Solution:def maxProfit(self, k: int, prices: List[int]) -> int:if not prices:return 0n len(prices)k min(k, n // 2)buy [0] * (k 1)sell [0] * (k 1)buy[0], sell[0] -prices[0], 0for i in range(1, k 1):buy[i] …

尚硅谷vue2的todolist案例解析,基本概括了vue2所有知识点,结尾有具体代码,复制粘贴学习即可

脚手架搭建 1-初始化脚手架(全局安装) npm install -g vue/cli2-切换到创建项目的空目录下 vue create xxxx整体结构 整体思路 App定义所有回调方法 增删改查 还有统一存放最终数据,所有子组件不拿数据,由App下发数据&#xf…

App托管服务分发平台 index-uplog.php 文件上传致RCE漏洞复现

0x01 产品简介 App托管服务分发平台是一个为开发者提供全面、高效、安全的应用程序托管、分发和推广服务的平台。开发者可以将自己开发的应用程序上传到平台上,平台会对上传的应用程序进行审核,确保应用的质量和安全性。平台会根据开发者的要求,将应用分发到不同的应用市场…

5G RAN

两个entity:NodeB、UE entity之间传输数据的东东 entity内部的流水线岗位:L3/L2/L1 岗位之间是消息交互/信令交互

利用labelme制作自己的coco数据集(labelme转coco数据集)

最近刚接触学习mmdetection,需要用到coco格式的数据集。 1.安装labelme 建议在conda(base)环境下安装(前提是需要下载anaconda),下面是我已经装过的情况。 2.进入labelme环境下 中间可能会提示安装其它库,自行装上就行。 这里的…

Rtt与linux线程关键函数差异问题

rt_thread_startup和pthread_join()是两个用于处理线程的函数,但它们属于不同的线程库和操作系统环境,具有显著的功能差异。以下是它们的功能对比和差异说明: rt_thread_startup 功能: rt_thread_startup函数用于使初始化状态的…

Codeforces 220B

传送门 题目大意 给出一个长度为 n n n的序列,进行 m m m次询问。 每次询问区间 [ l , r ] [l,r] [l,r]内,有多少个数字 x x x刚好出现了 x x x次。 思路 枚举右端点 r r r,维护左端点 l l l,设法将 s u m ( l , r ) s u m (…

智能社区服务小程序的设计

管理员账户功能包括:系统首页,个人中心,用户管理,房屋信息管理,住户信息管理,家政服务管理,家政预约管理,报修信息管理 微信端账号功能包括:系统首页,房屋信…

Flood Fill——AcWing 1097. 池塘计数

Flood Fill 定义 Flood Fill算法,又称为洪水填充或种子填充算法,是一种在图或网格数据结构中探索连通区域的搜索算法。它从一个初始节点(种子点)开始,将具有相同属性(如颜色、值等)的相邻节点…

P4. 微服务: 匹配系统(下)

P4. 微服务: 匹配系统 下 0 概述1 游戏同步系统1.1 游戏同步的设计1.2 游戏同步的实现 2 匹配系统微服务的实现2.1 微服务概述2.2 匹配系统接口url的实现2.3 微服务之间的通信2.4 匹配逻辑的实现2.5 匹配系统的权限控制 3 bug的解决3.1 自己匹配自己3.2 断开连接问题 0 概述 本…