【Java动态代理】—— 每天一点小知识

news2025/2/5 8:53:07

在这里插入图片描述

                                                                              💧 J a v a 动态代理 \color{#FF1493}{Java动态代理} Java动态代理💧          


🌷 仰望天空,妳我亦是行人.✨
🦄 个人主页——微风撞见云的博客🎐
🐳 《数据结构与算法》专栏的文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺
💧 《Java学习笔记》专栏的文章是本人在Java学习中总结的一些知识点~ 💐
🥣 《每天一点小知识》专栏的文章可以丰富你的知识库,滴水成河~ 🌊
🪁 希望本文能够给读者带来一定的帮助~🌸文章粗浅,敬请批评指正!🐥


文章目录

  • 🐳Java动态代理
    • 1. 动态代理的概念
    • 2. 动态代理的用法
      • 2.1 接口 MyInterface
      • 2.2 接口实现类 MyClass
      • 2.4 代理处理器类 MyInvocationHandler
      • 2.5 示例演示
      • 2.6 调用之后的结果
      • 补充: InvocationHandler是什么
    • 3. 动态代理的工作原理
  • 🐳结语


🐳Java动态代理

在Java编程中,动态代理是一种强大的技术,可以在运行时创建代理对象,以便在不修改原始类代码的情况下对其进行扩展或修改。动态代理使得我们能够在调用方法前后插入自定义的逻辑,例如日志记录、性能监测、事务处理等。在本篇博客中,我将详细讲解Java动态代理的概念、用法,并提供代码示例,帮助你深入理解和应用该技术。


1. 动态代理的概念

💧在传统的代理模式中,我们需要为每个被代理的类手动编写代理类。而动态代理则允许我们在运行时创建代理对象,无需事先编写代理类。动态代理是通过Java的反射机制实现的,它允许我们在运行时创建接口的代理实例。

💧动态代理的核心是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类提供了创建代理类的静态方法,而InvocationHandler接口则定义了代理类需要实现的方法。

2. 动态代理的用法

💧让我们通过一个示例来演示动态代理的使用过程。假设我们有一个接口MyInterface,以及一个实现该接口的类MyClass。我们希望在调用MyClass的方法前后打印日志。

2.1 接口 MyInterface

💧接口MyInterface表示一个我们希望创建的动态代理对象的接口。在示例中,我们将使用一个简单的接口作为示范。以下是MyInterface的定义:

public interface MyInterface {
    void myMethod();
}

💧MyInterface接口中定义了一个名为myMethod的抽象方法。我们希望在调用该方法前后插入自定义的逻辑。通过动态代理,我们可以实现在调用myMethod方法时执行额外的操作。

2.2 接口实现类 MyClass

💧MyClass是一个实现了MyInterface接口的具体类。在示例中,我们将使用一个简单的MyClass类来作为被代理对象。以下是MyClass的定义:

public class MyClass implements MyInterface {
    @Override
    public void myMethod() {
        System.out.println("This is myMethod");
    }
}

2.4 代理处理器类 MyInvocationHandler

💧在演示前,我们还需要创建一个实现了InvocationHandler接口的代理处理器类。在该类中,我们可以定义在调用代理对象方法前后执行的逻辑。以下是MyInvocationHandler 的定义:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在调用方法前执行的逻辑
        System.out.println("Before method invocation");

        // 调用目标对象的方法
        Object result = method.invoke(target, args);

        // 在调用方法后执行的逻辑
        System.out.println("After method invocation");

        return result;
    }
}

💧在上述代码中,MyInvocationHandler实现了InvocationHandler接口,并重写了其中的invoke方法。在invoke方法中,我们可以根据需要在调用方法前后执行自定义的逻辑。其中,proxy参数表示生成的代理对象,method参数表示被调用的方法,args参数表示方法的参数数组。

2.5 示例演示

💧接下来,我们可以使用Proxy类的newProxyInstance方法创建代理对象。这个方法接受三个参数:类加载器(ClassLoader)、接口数组和代理处理器对象。示例如下:

import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
                MyClass.class.getClassLoader(),
                new Class[]{MyInterface.class},
                new MyInvocationHandler(myClass)
        );

        proxyInstance.myMethod();
    }
}

💧在上述代码中,我们创建了一个MyClass的实例myClass,然后使用Proxy.newProxyInstance方法创建了一个代理对象proxyInstance。该代理对象实现了MyInterface接口,并由MyInvocationHandler来处理方法的调用。最后,我们调用了代理对象的myMethod方法。

2.6 调用之后的结果

💧当我们运行上述示例代码时,将会得到以下输出:

Before method invocation
This is myMethod
After method invocation

💧可以看到,在调用代理对象的myMethod方法前后,MyInvocationHandler中定义的逻辑被执行了。这意味着我们成功地在方法调用前后插入了自定义的代码。

补充: InvocationHandler是什么

💧其实InvocationHandler是一个接口,位于java.lang.reflect包中。它定义了代理对象的方法调用处理逻辑。在使用动态代理时,我们需要实现该接口,并重写其中的invoke方法。

💧方法invoke接收三个参数:代理对象、被调用的方法和方法的参数。我们可以在该方法中定义在方法调用前后执行的逻辑。该方法的返回值为方法的返回值。

3. 动态代理的工作原理

💧当我们调用代理对象的方法时,实际上会调用代理对象的invoke方法。invoke方法中通过反射机制调用了被代理对象的相应方法,并在调用前后执行了自定义的逻辑。这样,我们就实现了动态代理的效果。


在这里插入图片描述


🐳结语

🐬初学一门技术时,总有些许的疑惑,别怕,它们是我们学习路上的点点繁星,帮助我们不断成长。

🐟积少成多,滴水成河。文章粗浅,希望对大家有帮助!

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

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

相关文章

PyTorch 深度学习处理多维特征的输入

import numpy as np import torch import matplotlib.pyplot as plt# prepare dataset xy np.loadtxt(diabetes.csv, delimiter,, dtypenp.float32) x_data torch.from_numpy(xy[:, :-1]) # 第一个‘:’是指读取所有行,第二个‘:’是指从第…

Linux常用命令——eject命令

在线Linux命令查询工具 eject 用来退出抽取式设备 补充说明 eject命令用来退出抽取式设备。若设备已挂入,则eject命令会先将该设备卸除再退出。 eject允许可移动介质(典型是cd-ROM、软盘、磁带、或者JAZ以及zip磁盘)在软件控制下弹出。该…

Visual Studio 2022打包exe ,自动按日期生成文件

echo offREM 获取当前的日期和时间 set YEAR%DATE:~0,4% set MONTH%DATE:~5,2% set DAY%DATE:~8,2% set HOUR%TIME:~0,2% set MINUTE%TIME:~3,2% set SECOND%TIME:~6,2%REM 获取原始文件名 set "FilePath$(TargetPath)" for %%F in ("%FilePath%") do (set…

第46节:cesium 水面效果(含源码+视频)

结果示例: 完整源码: <template><div class="viewer"><vc-viewer @ready="ready" :logo="false"><!

【AT89C52单片机项目】99累减器

实验目的 掌握STC89C52RC单片机最小系统构成&#xff0c;最小系统由单片机芯片、时钟电路及复位电路组成。 掌握STC89C52RC单片机开发板与数码管的原理图、控制方式。 掌握对单片机I/O的复杂控制 熟练掌握C语言的设计和调试方法。 实验仪器 一套STC89C52RC开发板套件&…

Linux C/C++实现Socks5代理及Socks5协议抓包分析

如果你想在保持匿名的同时以更好的安全性和性能浏览网页&#xff0c;SOCKS5代理是一个不错的选择。 在使用互联网时&#xff0c;存在许多安全和数据隐私风险。此外&#xff0c;您可能不得不面对一些限制。想象一下&#xff0c;你想访问一个网站&#xff0c;但你根本无法访问它&…

【MySQL】从执行计划了解MySQL优化策略

文章目录 前言一、什么是执行计划1.1. 使用EXPLAIN命令1.2. 使用PROFILING 二、执行计划生成过程三、执行计划的操作符3.1. 查询计划操作符3.2. 连接操作符3.3. 辅助操作符 四、执行计划的诊断分析4.1. 使用EXPLAIN命令4.2. 检查索引4.3. 分析查询日志 五、如何分析 EXPLAIN 结…

pytorch 欠拟合和过拟合 多项式回归

欠拟合 训练误差和验证误差都有&#xff0c;还可能比较严重&#xff0c; 但它们之间仅有差距不大。 这个时候模型不能降低训练的误差&#xff0c;有可能是我们设计的模型简单了&#xff0c;表达能力不足&#xff0c; 捕获试图学习的模式比较难。由于我们的训练和验证误差之间的…

java——this、封装、static修饰成员变量、成员方法

目录 ☂️this的用法 1.访问当前对象的成员变量 2.访问当前对象的成员方法 3.调用当前对象的其他构造方法来简化代码 ☂️封装 什么是封装&#xff1f; 访问修饰限定符 ☂️static修饰成员变量 ☂️static修饰成员方法 ☂️this的用法 1.访问当前对象的成员变量 我们…

容器运行时

容器运行时 Docker运行时Containerd运行时CRI 版本支持Containerd安装配置 systemd cgroup 驱动 CRI-O运行时Mirantis 容器运行时 目前k8s支持的几个常用的运行时 containerdCRI-ODocker EngineMirantis Container Runtime v1.24 之前的 Kubernetes 版本直接集成了 Docker Engi…

IDEA+spring boot+activiti+shiro+layui+Mysql权限管理系统源码

IDEAspring bootactivitishirolayuiMysql权限管理系统 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.主页3.用户管理4.部门管理5. 菜单管理6. 角色管理7. 字典管理8.定时任务9.操作日志10.生成管理 三、部分代码UserMapper.javaUserController.javaUser.java 四、其他获…

Python Flask构建微信小程序订餐系统 (七)

🔥 账号管理显示状态 🔥 账号管理选择状态后并显示 修改前 修改后 运行效果 🔥 账号管理执行账号的删除 🔥 修改前 修改后 这里使用的图标库 font awesome</

引入Vue的方式

1.cdn引入 <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

竞赛管理系统实现自动化测试

目录 一、为竞赛管理系统设计测试用例 二、根据测试用例进行测试 登录页面测试 功能测试 界面测试 用户注册页面 功能测试 界面测试 竞赛信息列表页面测试 界面测试 添加竞赛信息页面测试 功能测试 界面测试 修改竞赛信息页面测试 功能测试 一、为竞赛管理…

Rollup 的作用、使用教程、支持 Vue、以及与 Webpack / Babel 的区别

一、前置知识 没接触过前端模块化概念的同学可先参考&#xff1a;JS & Node 模块化解释&#xff1a;AMD、UMD、CommonJS、 ESM 二、什么是 Rollup &#xff1f; Rollup 工具可以将代码转成不同模块&#xff0c;实现一套代码多端&#xff08;浏览器/Node&#xff09;引入…

SpringBoot的静态资源文件访问问题

一、采用默认的文件存放位置&#xff1a; Spring Boot 对静态资源映射提供了默认配置&#xff0c; 默认将 /** 所有访问映射到以下目录&#xff1a; classpath:/static classpath:/public classpath:/resources classpath:/META-INF/resources在如上路径的文件可以被直接访问…

Havoc!新的开源命令和控制C2框架

工具介绍 Havoc是一款现代化可扩展的后渗透命令控制框架&#xff0c;可作为Cobalt Strike和Brute Ratel等付费选项的替代方案。 关注【Hack分享吧】公众号&#xff0c;回复关键字【230618】获取下载链接 Havoc包含各种各样的模块&#xff0c;允许渗透测试人员&#xff08;和黑…

Rust 数据类型 之 结构体(Struct)

目录 结构体&#xff08;Struct&#xff09; 定义与声明 结构体定义 结构体实例 结构体分类 单元结构体&#xff08;Unit Struct&#xff09; 元组结构体&#xff08;Tuple Struct&#xff09; 具名结构体&#xff08;Named Struct&#xff09; 结构体嵌套 结构体方法…

华为云ROMA Connect 的智能集成 – 现代企业数字化转型的新利器

在当今数字信息智能化的时代&#xff0c;人工智能技术逐渐深入企业的生产流程和实践中。人工智能的应用成为现代企业数字化转型的新利器。华为云的ROMA Connect作为企业级的融合集成服务 EiPaaS平台&#xff0c;从今年开始也进入了人工智能技术&#xff0c;针对几个主要的企业集…

新一代iPaaS全域融合集成平台ROMA Connect HDC.Cloud 2023内容值得再读!

华为云下一代ROMA Connect HDC.Cloud 2023 精彩内容摘要&#xff1a; 7月9号 分论坛上嘉宾分享一站式融合集成平台解决的用户痛点、应用场景、新一代全域升级的新特性、以及伙伴分享案例干活 ROMA Connect 展台提供开发者体验全新升级版ROMA Connect的 AI智能集成 HDC.Cloud…