java基础-chapter16(动态代理)

动态代理

特点:无侵入式的给代码增加额外的功能

在Java中,动态代理是一种在运行时动态生成代理对象的机制,而不需要在编译时确定代理类。它允许在运行时创建一个实现了一组特定接口的代理类,这些代理类可以将方法调用转发到实际对象,并且可以在调用前后添加额外的逻辑。动态代理通常与反射机制结合使用。

Java中实现动态代理的主要类和接口有两个:java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。

  1. java.lang.reflect.Proxy类:

    • Proxy类是用于创建动态代理类和实例的工具类。
    • Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)方法用于创建代理对象。
    • 参数loader指定了用于加载代理类的类加载器,interfaces指定了代理类要实现的接口,handler指定了代理对象的调用处理程序。
  2. java.lang.reflect.InvocationHandler接口

    • InvocationHandler是一个函数式接口,它只包含一个方法invoke(Object proxy, Method method, Object[] args),在代理对象的方法被调用时会被调用。
    • proxy参数是代理对象本身,method参数是被调用的方法对象,args参数是方法的参数。

使用动态代理的步骤通常如下:

  1. 定义一个接口,该接口表示要被代理的对象的功能。
  2. 实现InvocationHandler接口,编写代理对象的调用处理逻辑。
  3. 使用Proxy.newProxyInstance()方法创建代理对象。
  4. 通过代理对象调用方法,代理对象会将方法调用转发给InvocationHandlerinvoke()方法进行处理。

动态代理常用于以下情况:

  • AOP(面向切面编程):在方法执行前后添加日志、性能监控等功能。
  • RPC(远程过程调用):通过动态代理实现远程接口的调用。
  • 事件监听器:动态生成事件监听器的代理对象来处理事件。

总的来说,动态代理使得编程更加灵活,可以在运行时动态地创建代理对象,并且可以在方法调用前后添加额外的逻辑,从而实现一些高级功能。

1.Java提供了什么API帮我们创建代理?

Java提供了java.lang.reflect.Proxy类来帮助创建代理对象。这个类提供了一个静态方法newProxyInstance(),可以用来创建动态代理对象。具体来说,Proxy.newProxyInstance()方法允许你传入一个类加载器(ClassLoader)、一组接口(Interface)以及一个InvocationHandler对象,然后它会返回一个实现了指定接口的代理对象。

这个方法的签名如下:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler handler)
  • loader 参数是用来加载代理类的类加载器。
  • interfaces 参数是一个接口数组,指定了代理类要实现的接口。
  • handler 参数是一个 InvocationHandler 对象,用于处理代理对象的方法调用。

通过Proxy.newProxyInstance()方法创建的代理对象会实现指定的接口,并且会将方法调用转发给传入的InvocationHandler对象的invoke()方法进行处理。

2.newlProxylnstance方法在创建代理时,需要接几个参数,每个参数的含义是什么?

Proxy.newProxyInstance()方法在创建代理时需要接收三个参数,每个参数的含义如下:

  1. ClassLoader loader:用于加载代理类的类加载器。这个参数指定了在运行时动态生成代理类的类加载器。通常情况下,你可以传入你的类的类加载器,例如 YourClass.class.getClassLoader(),或者传入系统类加载器,例如 ClassLoader.getSystemClassLoader()

  2. Class<?>[] interfaces:一个接口数组,指定了代理类要实现的接口。代理类会实现这些接口中的方法,并将方法调用转发给 InvocationHandler 对象进行处理。

  3. InvocationHandler handler:一个 InvocationHandler 对象,用于处理代理对象的方法调用。当代理对象的方法被调用时,会调用 InvocationHandler 对象的 invoke() 方法进行处理。在 invoke() 方法中,你可以添加额外的逻辑,比如日志记录、权限检查等。

3.通过invokehandler的invoke方法指定代理干的事时,这个invoke会被谁调用? 要接哪几个参数?

InvocationHandler 接口中的 invoke() 方法在代理对象的方法被调用时会被代理对象自动调用。这个方法会接收以下几个参数:

  1. Object proxy:代理对象本身。在 invoke() 方法中,你可以通过这个参数来调用被代理对象的方法。

  2. Method method:被调用的方法对象。通过这个参数,你可以获取方法的名称、参数类型等信息。

  3. Object[] args:方法的参数数组。通过这个参数,你可以获取方法的参数值。

invoke() 方法中,你可以根据需要处理代理对象的方法调用,比如记录日志、添加权限检查等,然后决定是否调用被代理对象的方法。最后,你需要返回方法的执行结果(如果有)给调用者。

学习代码:

测试类

public class Test {public static void main(String[] args) {//获取代理的对象BigStar bigStar = new BigStar("蔡徐坤");Star proxy = ProxyUtil.createProxy(bigStar);//再调用代理的唱歌方法String name = proxy.sing("只因你太美");System.out.println(name);//调用跳舞的方法proxy.dance();}
}

明星类

public class BigStar implements Star{private String name;//唱歌 跳舞public String sing(String name){System.out.println(this.name+"正在唱"+name);return "谢谢";}public void dance(){System.out.println(this.name+"正在跳舞");}public BigStar(String name) {this.name = name;}public BigStar() {}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "BigStar{" +"name='" + name + '\'' +'}';}
}

明星接口类

public interface Star {public abstract String sing(String name);public abstract void dance();
}

代理类

//类的作用:创建一个代理
public class ProxyUtil {/* 方法的作用:给一个明星的对象,创建一个代理形参:被代理的明星对象返回值:给明星创建的代理*/public static Star createProxy(BigStar bigStar){Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), //参数loader指定了用于加载代理类的类加载器new Class[]{Star.class}, //interfaces指定了代理类要实现的接口new InvocationHandler() { //handler指定了代理对象的调用处理程序@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if ("sing".equals(method.getName())){System.out.println("准备唱歌,收钱");} else if ("dance".equals(method.getName())) {System.out.println("准备跳舞,收钱");}return method.invoke(bigStar,args);}});return star;}
}

(代码仅供参考)

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

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

相关文章

面试-数据库基础以及MySql、ClickHost、Redis简介

面试-数据库基础以及MySql、ClickHost、Redis简介 0.数据完整性1.数据库并发控制1.1事物1.2 并发读写错误1.3 锁1.3.1 乐观锁与悲观锁1.3.2 共享锁和排他锁1.3.3 行锁与表锁1.3.4 意向锁 1.4 封锁协议与隔离级别1.5 MVCC1.5.1 概念1.5.2 当前读与快照读1.5.3 MVCC in InnoDB 2.…

pytest常用钩子函数

1、什么叫钩子函数 在Pytest框架中&#xff0c;钩子函数是一种允许用户扩展或者自定义测试执行过程的机制。钩子函数允许用户在测试的不同阶段插入自定义的代码&#xff0c;以实现特定的行为&#xff0c;操作或处理。这种插入式的机制使得Pytest具有高度的灵活性和扩展性。 如…

Linux软件包管理器yum—5

一、Linux下软件安装的方式 ①源代码安装&#xff1a; ②rmp包安装&#xff1a; 本质是拷贝可执行程序到系统目录下。 ③yum一键下载&#xff0c;安装&#xff0c;卸载。相当于手机的应用商店。 二、yum 2.1查看yum已配置的源&#xff1a; ls /etc/yum.repos.d/ 2.2查看yum…

环信 IM 客户端将适配鸿蒙 HarmonyOS

自华为推出了自主研发操作系统鸿蒙 HarmonyOS 后&#xff0c;国内许多应用软件开始陆续全面兼容和接入鸿蒙操作系统。环信 IM 客户端计划将全面适配统鸿蒙 HarmonyOS &#xff0c;助力开发者快速实现社交娱乐、语聊房、在线教育、智能硬件、社交电商、在线金融、线上医疗等广泛…

HarmonyOS实战开发-横竖屏切换

介绍 本实例展示如何使用媒体查询&#xff0c;通过ohos.mediaquery 接口完成在不同设备上显示不同的界面效果。 效果预览 使用说明 1.在竖屏设备上&#xff0c;首页展示新闻列表&#xff0c;点击新闻进入详情界面。 2.在横屏设备上&#xff0c;首页左侧展示新闻列表&#x…

010、Python+fastapi,第一个后台管理项目走向第10步:ubutun 20.04下安装ngnix+mysql8+redis5环境

一、说明 先吐槽一下&#xff0c;ubuntu 界面还是不习惯&#xff0c;而且用的是云电脑&#xff0c;有些快捷键不好用&#xff0c;只能将就&#xff0c;谁叫我们穷呢&#xff1f; 正在思考怎么往后进行&#xff0c;突然发现没安装mysql 和redis&#xff0c;准备安装&#xff0…

系统架构最佳实践 -- 高并发解决单用户超领优惠券问题

问题抛出 在近期的项目里面有一个功能是领取优惠券的功能&#xff0c; 问题描述&#xff1a; 每一个优惠券一共发行多少张&#xff0c;每个用户可以领取多少张&#xff1a; 如&#xff1a;A优惠券一共发行120张&#xff0c;每一个用户可以领取140张&#xff0c;当一个用户领…

网桥的原理

网桥的原理 1.1 桥接的概念 简单来说&#xff0c;桥接就是把一台机器上的若干个网络接口“连接”起来。其结果是&#xff0c;其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。 交换机就是这样一个设备&#xff0c;它有若干个网口…

【13137】质量管理(一)2024年4月串讲题组一

目录 1.选择题 2.多选题 3.简答题 4.论述题 5.计算题 6.论述题 【13137】质量管理-速 记 宝 典【全国通用】</

5.0 HDFS 集群

5.0 HDFS 集群 分类 编程 HDFS 集群是建立在 Hadoop 集群之上的&#xff0c;由于 HDFS 是 Hadoop 最主要的守护进程&#xff0c;所以 HDFS 集群的配置过程是 Hadoop 集群配置过程的代表。 使用 Docker 可以更加方便地、高效地构建出一个集群环境。 每台计算机中的配置 Hado…

2024最新数据分级分类的架构方法流程指南(附下载)

以下是资料目录&#xff0c;如需下载请前往知识星球下载&#xff1a;https://t.zsxq.com/18KTZnJMX

爬虫ip被限制了怎么解决

在新手开发爬虫功能的时候&#xff0c;很容易出现单个ip被冻结事件。 What: 最简单的表现就是拿不到相应的数据流。 Why: ip被冻结是什么原因 How: 肯定就是网上提供的一些比较基础的方法&#xff0c;分分钟就可以上手。 user_agent 伪装和轮换 不同浏览器的不同版本都有不…

中药分类大全数据库|(收载CDE数据及中药注册分类数据)

中药是指根据中医药理论和实践经验&#xff0c;用以预防、治疗和诊断疾病以及调节机体功能的药材和成药。像中药材、中药饮片、中成药、方剂、药材提取物、配方颗粒、外用中药、特殊用途中药等都可以统称为中药&#xff0c;所以说中药的分类方法多种多样&#xff0c;笔者精心整…

【Canvas与艺术】绘制黄色三角生化危险标志

【关键点】 系统函数arcTo函数的用法及自编函数createRegTriArr的灵活运用。 【成果图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head>&…

【STL】vector

目录 1. vector的使用 1.1 vector的定义 1.2 vector iterator 的使用 1.3 vector 空间增长问题 1.4 vector 增删查改 1.5 vector 迭代器失效问题&#xff08;重点&#xff09; 2.vector模拟实现 1. vector的使用 1.1 vector的定义 1.2 vector iterator 的使用 1.3 vecto…

Java代码基础算法练习-自定义函数之求字符串长度-2024.04.13

任务描述&#xff1a; 写一函数&#xff0c;求一个字符串的长度&#xff08;字符串长度不超过255&#xff09;&#xff0c;然后在主函数中调用该函数 实现求长度操作。 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner;public class …

如何获取手机root权限?

获取手机的 root 权限通常是指在 Android 设备上获取超级用户权限&#xff0c;这样用户就可以访问和修改系统文件、安装定制的 ROM、管理应用权限等。然而&#xff0c;需要注意的是&#xff0c;获取 root 权限可能会导致手机失去保修、安全性降低以及使系统变得不稳定。在获取 …

电脑的日常使用 0 笔记本电脑验机使用体验帖

拯救者 Y7000P 2023 win11系统&#xff08;首发&#xffe5;6999&#xff09; 目录 开机前准备 开机后的验机工作 基本配置 一、 外观及使用体验 二、内部硬件使用体验 1.固态 3. CPU 4.显卡 总结 开机前准备 注意一定要全程录像 &#xff01; 检查快递外包装壳&#…

数据的未来:人工智能引领下的大数据革命

大数据是指在一定时间范围内&#xff0c;无法通过常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;这种数据具有海量、高增长率和多样化的特点&#xff0c;需要采用新的处理模式才能发挥其更强的决策力、洞察发现力和流程优化能力。大数据将数据视为核心资源&#xff0…

Spring Boot | Spring Boot 整合 “Servlet三大组件“ ( Servlet / Filter / Listene )

目录: Spring Boot 整合 "Servlet三大组件" &#xff1a;1. 使用 "组件注册" 的方式 "整合Servlet三大组件" ( 实际操作为 : 创建自定义的"三大组件"对象 结合刚创建"的自定义组件对象"来 将 XxxRegistrationBean对象 通过…