Java的静态代理与jdk动态代理

代理

我们经常利用代理进行解耦以及控制对实际对象的访问等工作。例如,我们可以通过代理对方法的调用进行更精细的控制(例如加上日志、权限控制等),而无需修改实际对象的代码。代理的作用是无侵入式的给代码增加功能。有些事情是对象不想做或者不能做的,就可以通过代理来实现。
代理一般有三种模式:

  1. 静态代理
  2. jdk动态代理
  3. cglib动态代理(这里不做过多赘述)

静态代理

静态代理很简单,我们通过代码来理解就很方便。

package TestProcxy;public class ProTest {public static void main(String[] args) {Father father = new Father();father.eat();}
}class Per{public void eat(){System.out.println("吃饭!!!");}
}class Father{Per per = new Per();public void eat(){System.out.println("拿筷子~~~~");per.eat();System.out.println("洗碗~~~~");}
}

运行结果
![[Pasted image 20240329095713.png]]

jdk动态代理

代理里面就是对象要被代理的方法。java通过接口来保证代理的样子,即对象和代理要实现同一个接口中的方法就是被代理的所有方法。
代理可以增强或者拦截的方法都在接口中,接口需要写在newProxyInstance的第二个参数里。

package TestProxy;/*** 接口* 通过接口来进行代理*/
public interface Event {void eat(String something);
}package TestProxy;public class Per implements Event {String name;public Per(String name) {this.name = name;}@Overridepublic void eat(String something) {System.out.println(name + "吃" + something + "!!!");}
}package TestProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class PerProxy {public static Event createProxy(){/*** java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)* 参数一:用于指定用哪个类加载器去加载生成的代理类* 参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法* 参数三:用来指定生成的代理对象要干什么事情*/Object o = Proxy.newProxyInstance(PerProxy.class.getClassLoader(),new Class[]{Event.class},new InvocationHandler() {/** 参数一:代理的对象* 参数二:要运行的方法 eat* 参数三:调用eat方法时,传递的实参* */@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("拿筷子~~~");method.invoke(new Per("张三"), args);System.out.println("洗碗~~~");return null;}});return (Event) o;}
}package TestProxy;public class ProTest {public static void main(String[] args) {PerProxy perProxy = new PerProxy();Event proxy = perProxy.createProxy();proxy.eat("刀削面");}
}

运行结果
![[Pasted image 20240329110824.png]]

练习

对List的add方法进行增强,对remove方法进行拦截。

package TestProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;public class EnhanceList {public static void main(String[] args) {List list = new ArrayList();Object o = Proxy.newProxyInstance(EnhanceList.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 对原List的add方法进行增强if (method.getName().equals("add")) {System.out.println("对list新增了" + args[0]);return method.invoke(list, args);} else if (method.getName().equals("remove")) {// 拦截根据索引删除的方法是正常的,如果拦截根据对象删除的方法就会报错,因为他们的返回值不一样System.out.println("拦截了remove方法");return null;} else {return method.invoke(list, args);}}});List proxyList = (List) o;proxyList.add("aaa");proxyList.add("bbb");proxyList.add("ccc");proxyList.add("ddd");proxyList.remove(0);proxyList.remove("aaa");System.out.println(list);}
}

这段代码是由问题的就是在拦截remove方法时的问题,因为remove重载了两种方法,返回值类型也不一样(一个是布尔类型,另一个是对象),而我们在拦截时只返回了null,因此会报错。
运行结果
![[Pasted image 20240329114907.png]]

正确的修改
![[Pasted image 20240329115006.png]]

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

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

相关文章

sql——对于行列转换相关的操作

目录 一、lead、lag 函数 二、wm_concat 函数 三、pivot 函数 四、判断函数 遇到需要进行行列转换的数据处理需求&#xff0c;以 oracle 自带的表作为例子复习一下&#xff1a; 一、lead、lag 函数 需要行列转换的表&#xff1a; select deptno,count(empno) emp_num from…

第十四届蓝桥杯JavaA组省赛真题 - 互质数的个数

解题思路&#xff1a; 快速幂 欧拉函数 快速幂比较常见于数据较大的取模场景&#xff0c;欧拉函数感觉还是有点抽象 注意&#xff1a; 取模的时候就不要简写了&#xff0c;例如&#xff1a;res res * a % mod;不要写成res * a % mod; import java.util.Scanner;public c…

算法之美:B+树原理、应用及Mysql索引底层原理剖析

B树的一种变种形式&#xff0c;B树上的叶子结点存储关键字以及相应记录的地址&#xff0c;同等存储空间下比B-Tree存储更多Key。非叶子节点不对关键字记录的指针进行保存&#xff0c;只进行数据索引 , 树的层级会更少 , 所有叶子节点都在同一层, 叶子节点的关键字从小到大有序排…

直流马达驱动芯片D6289ADA介绍

应用领域 适用于智能断路器&#xff08;家用或工业智能空开&#xff09;、新能源汽车充电枪锁、电动玩具、电磁门锁、自动阀门等的直流电机驱动。 功能介绍 D6289ADA是一款直流马达驱动芯片&#xff0c;它有两个逻辑输入端子用来控制电机前进、后退及制动。该电路具有良好的抗干…

如何解决 IntelliJ IDEA 中属性文件的编码问题

在使用 IntelliJ IDEA 进行开发过程中&#xff0c;我们经常会遇到属性文件&#xff08;.properties 文件&#xff09;的编码问题。如果属性文件的编码设置不正确&#xff0c;就会导致中文等特殊字符显示乱码。这是因为IntelliJ IDEA中默认的配置文件的编码格式是ISO-8859-1。 …

36-递归与迭代

36-1 用递归和迭代解决问题 1、求n的阶乘 公式&#xff1a; n!123...(n-1)n。用递归方式定义&#xff1a;0!1&#xff0c;n!(n-1)!n。 代码1&#xff1a; 我们先回忆一下之前用循环怎么实现的吧 非递归&#xff0c;也可称迭代&#xff1a; int main() {int n 0;scanf(&q…

精酿啤酒:酿造工艺的创新与实验探索

在啤酒酿造领域&#xff0c;创新与实验探索一直是推动品质提升和品类丰富的重要动力。Fendi Club啤酒作为一家注重品质和口感的品牌&#xff0c;在酿造工艺方面不断创新与尝试&#xff0c;为消费者带来更多与众不同的风味体验。 Fendi Club啤酒在原料选择方面不断进行创新与实验…

超级码科技股份携手品品香开数字茶业新范式,实现全产业链数智化闭环

品品香白茶创立于1992年&#xff0c;品牌创立的30多年间&#xff0c;品品香不断创新技术、精耕细作、推陈出新&#xff0c;在不同发展时期始终走在行业前沿&#xff0c;助推着白茶产业高质量发展。 2016年&#xff0c;品品香发挥茶产业龙头示范作用率先进行转型&#xff0c;联…

jmeter中参数加密

加密接口常用的方式有&#xff1a; MD5&#xff0c;SHA&#xff0c;HmacSHA RSA AES&#xff0c;DES&#xff0c;Base64 压测中有些参数需要进行加密&#xff0c;加密方式已接口文档为主。 MD5加密 比如MD5加密的接口文档&#xff1a; 请求URL&#xff1a;http://101.34.221…

免费VPS/云服务器整理汇总

随着互联网的普及和云计算技术的飞速发展&#xff0c;越来越多的人开始尝试使用VPS&#xff08;Virtual Private Server&#xff0c;虚拟专用服务器&#xff09;或者云服务器来部署自己的在线业务。本文将对免费VPS/云服务器进行整理汇总&#xff0c;助力大家轻松开启云计算之旅…

顺应互联网发展大潮流,红河农资招商火爆开启

顺应互联网发展大潮流&#xff0c;红河农资招商火爆开启 进入新世纪&#xff0c;生态农业建设成为了影响和改变农村、农业工作的重要领域。尤其是在互联网的快速发展之下&#xff0c;实现农业结构调整&#xff0c;推动互联网模式的发展&#xff0c;成为了当前生态农业发展的主流…

​python学习之变量类型​

print单纯输中的十种数据类型只需要用print()函数即可&#xff0c;()里面直接写变量名。 下面重点介绍print格式输出&#xff1a; 第一种方法&#xff1a;一个萝卜一个坑&#xff0c;下面的代码中&#xff0c;{0}、{1}、{2}分别表示j,i,j*i&#xff0c;单引号里面是输出格式。…

网络七层模型之表示层:理解网络通信的架构(六)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Python中模块

基本概念 **模块 module&#xff1a;**一般情况下&#xff0c;是一个以.py为后缀的文件 ①Python内置的模块&#xff08;标准库&#xff09;&#xff1b; ②第三方模块&#xff1b; ③自定义模块。 包 package&#xff1a; 当一个文件夹下有 init .py时&#xff0c;意为该文…

构建ELK+Filebeat+kafka+zookeeper大数据日志分析平台

主机IP 角色 所属服务层 部署服务 192.168.11.11 日志生产 采集层 filebeat 192.168.11.12 日志缓存 数据处理层、缓存层 Zookeeperkafkalogstash 192.168.11.13 192.168.11.14 日志展示 持久、检索、展示层 Logstashelasticsearchkibana 数据流向 filebeat--…

工业设备故障诊断解决方案 | 流数据实时采集、存储与回放

工业物联网场景中&#xff0c;故障分析是一个关键环节。设备发生故障时&#xff0c;需快速定位原因。实时采集的流式数据和操作日志记录了设备当前的运行状态&#xff0c;如何根据这些数据快速定位故障发生原因是一个值得研究的问题。DolphinDB 历史数据回放框架为故障分析提供…

极速上架:探索常用的苹果应用商店上架工具,提高应用发布效率

摘要 移动应用app上架是开发者关注的重要环节&#xff0c;但常常会面临审核不通过等问题。为帮助开发者顺利完成上架工作&#xff0c;各种辅助工具应运而生。本文探讨移动应用app上架原理、常见辅助工具功能及其作用&#xff0c;最终指出合理使用工具的重要性。 引言 移动应…

【Vue3进阶】- 第2学堂小商城实战课程前言

该教程为进阶教程&#xff0c;如果你还不了解Vue3的基础知识&#xff0c;可以先前往Vue3基础教程&#xff0c;从入门到实战。 学习时遇到的任何疑问都欢迎在相应课文页面下方的问答区进行提问哦 我能学到什么&#xff1f; 编程写法千千万&#xff0c;实现需求是第一。 教程中…

重塑未来:Web3如何改变我们的数字生活

引言 随着科技的飞速发展&#xff0c;Web3已经成为数字时代的新潮流&#xff0c;其革命性的变革正在渐渐改变着我们的数字生活。本文将深入探讨Web3如何改变我们的数字生活&#xff0c;涉及其意义、应用场景、对未来的影响&#xff0c;以及我们如何适应这一变革&#xff0c;为…

MySQL创建表:练习题

练习题&#xff1a; 创建一个名为"students"的数据库&#xff0c;并切换到该数据库。 在"students"数据库中创建一个名为"grades"的表&#xff0c;包含以下字段&#xff1a; id: 整数类型 name: 字符串类型&#xff0c;学生姓名 subject: 字符串…