【Java 基础】30 JDK动态代理

news2024/11/18 13:28:56

文章目录

    • 1.定义
    • 2.原理
    • 3.使用
      • 1)定义业务接口
      • 2)实现 InvocationHandler 接口
      • 3)生成代理类
    • 4.优点
    • 5.缺点
    • 总结

动态代理是一种重要的 设计模式,它允许在运行时生成代理类来代替实际的类。动态代理主要通过反射机制实现,为开发者提供了一种灵活且强大的方式来实现 AOP(面向切面编程)等功能。

1.定义

动态代理是一种在运行时生成代理类的机制,这些代理类在程序运行时创建,而不是在编译时静态定义。 JDK 动态代理主要基于 Java 的反射机制,通过在运行时创建代理类和对象,实现对实际类的代理。

动态代理通常用于在不修改原始类代码的情况下,向现有类添加额外的功能,例如日志记录性能监控事务处理等。

2.原理

JDK 动态代理的核心在于 java.lang.reflect 包中的 Proxy 类和 InvocationHandler 接口。代理类的创建过程主要包括以下步骤:

在这里插入图片描述

  • 定义接口: 定义一个业务接口,该接口将被动态代理类实现。
  • 实现 InvocationHandler 接口: 创建一个实现 InvocationHandler 接口的类,该类中包含了对原始类方法的代理逻辑。
  • 生成代理类: 使用 Proxy.newProxyInstance 方法生成代理类的实例,该方法需要传入类加载器、业务接口和 InvocationHandler 实现。
  • 调用代理方法: 通过代理类实例调用方法时,实际会调用到 InvocationHandler 中的 invoke 方法,从而执行代理逻辑。

3.使用

1)定义业务接口

interface Stu {
    void say(String name);
}

2)实现 InvocationHandler 接口

class HelloInvocationHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        // 增加前处理
        System.out.println("执行方法前: " + method.getName());

        // 执行原始方法 say
        System.out.println("Hello, " + args[0]);

        // 增加后处理
        System.out.println("执行方法后: " + method.getName());

        return null;
    }
}

3)生成代理类

public class Demo {
    public static void main(String[] args) {
        // 创建 InvocationHandler 实例
        HelloInvocationHandler invocationHandler = new HelloInvocationHandler();

        // 生成代理类实例
        Stu proxy = (Stu) Proxy.newProxyInstance(
                Stu.class.getClassLoader(),
                new Class[] { Stu.class },
                invocationHandler
        );

        // 调用代理方法
        proxy.say("Cheney");
    }
}

输出结果:

执行方法前: say
Hello, Cheney
执行方法后: say

在上述示例中,HelloInvocationHandler 类实现了 InvocationHandler 接口,通过在代理方法的前后添加日志记录,这也就是传说中的 AOP 面向切面编程的效果。

4.优点

  • 灵活性: 动态代理可以代理任意实现了接口的类,不受具体类的限制。
  • 简化代码: 动态代理可以避免编写大量重复的代理类代码,减少代码冗余。
  • 解耦合: 动态代理实现了代理逻辑和业务逻辑的解耦,使得代理类可以复用于不同的业务场景。

5.缺点

  • 只能代理接口: JDK 动态代理只能代理实现了接口的类,对于没有实现接口的类无法进行代理。
  • 性能相对较低: 由于动态代理是在运行时生成代理类,因此相比静态代理,其性能相对较低。

总结

JDK 动态代理是一种强大而灵活的设计模式,它通过在运行时生成代理类来实现对实际类的代理,为实现 AOP 等功能提供了便捷的方式。通过使用 Proxy 类和 InvocationHandler 接口,开发者可以轻松地创建动态代理。虽然 JDK 动态代理有一些限制,如只能代理实现了接口的类,性能相对较低等,但在大多数场景下,其优势远远大于缺点,使得它成为 Java 编程中不可或缺的一部分。

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

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

相关文章

计算机图形学——消隐算法

目录 消隐算法 (1)隐藏线消除算法 (2)隐藏面消除算法 曲面体消隐算法 3D Mesh 隐藏面消除算法 (1)深度缓冲器算法(zBuffer) 深度缓冲器 (2)深度排序…

机器学习基础介绍

百度百科: 机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。 …

mysql 链接超时的几个参数详解

mysql5.7版本中,先查看超时设置参数,我们这里只关注需要的超时参数,并不是全都讲解 show variables like %timeout%; connect_timeout 指的是连接过程中握手的超时时间,在5.0.52以后默认为10秒,之前版本默认是5秒,主…

学习人工智能-基础篇

背景 随着大模型的火爆,人工智能再次被推到高潮,其实它在众多行业领域已经落地很多应用,并给社会带来了巨大的经济价值。其中包括互联网、教育、金融、医疗、交通、物流等等。在测试领域也有一些落地的案例,作为测试人员&#xf…

关于个人职业选择

职业选择,一直是个老生常谈的话题。这并不是一个容易做的决定。 让我们来看看AI怎么说。 首先是方向性的回答: 然后是一些具体的回答 我个人比较倾向于深耕网络安全。这是一个很有趣也是一个持续发展着的领域。 不知道关于这个事情你怎么看&#xff0…

案例解决Redis高并发场景带来的缓存穿透、击穿、雪崩问题(超级详细!!)

假设你的网站流量量达到亿级,传统的去查询DB势必会给DB带来巨大的压力,甚至可能有宕机的风险,接下来我就分几个阶段,来讲诉各个场景可能会给DB带来巨大压力的可能,以及优化的方案。 缓存击穿:key对应的数据…

2023年12月11日:ui界面跳转

头文件&#xff1a;Second #ifndef SECOND_H #define SECOND_H#include <QWidget>namespace Ui { class Second; }class Second : public QWidget {Q_OBJECTpublic:explicit Second(QWidget *parent nullptr);~Second(); public slots:void jump_slot(); private:Ui::S…

飞桨星河文心SDK与open interpreter构成“小天网”雏形

飞桨星河文心SDK与open interpreter构成“小天网”雏形 开放式解释器open interpreter是大模型和自然语言交互的神器&#xff0c;本项目旨在体验文心大模型为底座的open interpreter。本项目只需使用CPU环境即可运行&#xff0c;直接运行即可“运行全部Cell”&#xff0c;本项…

访问控制列表ACL学习

ACL概念 ACL: ACL 是 Access Control List&#xff08;访问控制列表&#xff09;的缩写。它是一种用于管理和控制访问权限的机制或数据结构。ACL 用于确定谁可以访问特定资源&#xff08;例如文件、文件夹、网络资源等&#xff09;以及他们可以执行的操作。ACL 通常由一系列访…

【EMNLP 2023】面向Stable Diffusion的自动Prompt工程算法

近日&#xff0c;阿里云人工智能平台PAI与华南理工大学朱金辉教授团队合作在自然语言处理顶级会议EMNLP2023上发表了BeautifulPrompt的深度生成模型&#xff0c;可以从简单的图片描述中生成高质量的提示词&#xff0c;从而使文生图模型能够生成更美观的图像。BeautifulPrompt通…

1、混合方式UI设计

1、混合方式UI设计 新建项目添加静态资源添加资源添加action添加菜单菜单栏工具栏中间编辑区域 代码添加其他组件字体和大小状态栏 添加槽函数UI设置的转到槽的手写的设置应用程序图标 代码 新建项目 MainWindow代码文件夹主窗口为 (QMainWindow) 添加静态资源 AppIcon.icoi…

【MATLAB】基于CEEMDAN分解的信号去噪算法(基础版)

代码的使用说明 【MATLAB】基于CEEMDAN分解的信号去噪算法&#xff08;基础版&#xff09; 代码流程图 代码效果图 获取代码请关注MATLAB科研小白的个人公众号&#xff08;即文章下方二维码&#xff09;&#xff0c;并回复CEEMDAN去噪 本公众号致力于解决找代码难&#xff0c;…

【C++】POCO学习总结(十二):流(文本编解码、数据压缩、文件读写流等)

【C】郭老二博文之&#xff1a;C目录 1、说明 POCO提供了多种流类&#xff0c;与标准c IOStreams兼容。 大多数POCO流类被实现为过滤器&#xff0c;这意味着它们不写入或读取设备&#xff0c;而是从它们连接的另一个流。 2、文本编解码 2.1 说明 POCO提供了用于编码和解码…

苹果文本动态高亮,滚动时候部分高亮不显示问题

很简单的需求&#xff1a; 一个文本容器固定大小&#xff0c;内容超出滚动&#xff0c;然后文本点击高亮&#xff0c;奇怪就是苹果微信打开会出现点击只会高亮能看见的区域文本&#xff0c;滚动部分不会显示&#xff0c;默认浏览器打开也不行&#xff0c;安卓没问题&#xff0…

10.RIP路由信息协议

10.RIP 网段经常产生变化的话&#xff0c;建议使用动态路由协议&#xff0c;当网段发生变化的时候会自动通告给其他路由器 它不看链路的带宽&#xff0c;只看链路中的跳数&#xff0c;只要是跳数多的&#xff0c;不管带宽有多大&#xff0c;它就认为是不好的 RIP跳数有限 …

外包干了3个月,技术退步明显。。。

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

第三节、项目支付功能实战-微信支付平台接入流程,小程序账号注册、商户注册

简介 本篇介绍小程序的注册流程、商户平台的注册流程、以及小程序和商户平台如何进行绑定。 微信小程序注册 由于项目中使用了小程序进行支付&#xff0c;所以首先来注册小程序。小程序注册网站如下&#xff1a;小程序注册地址 小程序账号注册 1、链接页面点击“前往注册”…

事务的四个特性、四个隔离级别以及数据库的常用锁

事务的四个特性、四个隔离级别以及数据库的常用锁 四大特性 事务的四大特性&#xff0c;通常被称为ACID特性&#xff0c;是数据库管理系统&#xff08;DBMS&#xff09;确保事务处理的关键属性。这四大特性分别是&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#x…

银河麒麟v10系统SSH远程管理及切换root用户的操作方法

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一…

Python基础期末复习 新手 2

虽然age 10在__init__方法中定义了一个局部变量age&#xff0c;但这个局部变量并不会影响类属性age的值。类属性是在类级别上定义的&#xff0c;不属于任何一个实例。因此&#xff0c;在创建实例s1和s2时&#xff0c;它们的age属性值都为类属性的初始值0。 尽管对类的属性值进…