动态代理详解(原理+代码+代码解析)

动态代理

在这里插入图片描述

1.什么是动态代理?

动态代理是一种在运行的时候动态的生成代理对象的技术。它在不改变原始类的情况下,对原始类的方法进行拦截或者增强。

2.动态代理可以实现的功能?

使用动态代理可以实现如下常用功能:
1.AOP(面向切面编程):动态代理可以用于实现横切逻辑,例如日志记录,性能监控,事务管理等。通过在方法前后插入代理逻辑,可以实现对目标方法的增强。
2.远程方法调用(RPC):动态代理可以用于远程方法调用的框架,例如使用代理对象作为客户端的远程服务代理,将调用转发给实际的远程服务,并且可以将客户端或服务器的业务逻辑进行增强。
3.动态权限校验:动态代理可以用于动态权限校验,例如在访问某个受限资源的时候(我们假设是个方法),使用这个方法的对应对象的代理对象来调用这个方法的时候,在调用方法前可以增加权限判断的逻辑,如果权限对,就可以进入。

3.动态代理和静态代理的区别?

动态代理和静态代理最大的区别就是:静态代理是编译器确定的代理类,动态代理是运行期确定的代理类。
也就是说:
静态代理其实就是事先写好代理类,可以手动编写也可以使用工具生成,但是它的缺点就是每个业务类都需要一个代理类,因此维护性差,很不灵活也很不方便。
动态代理就是在运行期间,动态的创建目标对象的代理对象。它可以在不修改原始类的情况下
因此,他们两个最终的效果是一样的,都是可以在不修改原始类的代码的情况下,对代理对象的方法进行增强。只不过生成时间不同,和方式不同,静态代理需要给每个类手动创建代理对象,麻烦点罢了。

4.静态代理代码

代码比较简单,不过多解释,在动态代理的代码会详细解释

interface User{int age();void sayHi(String name);
}
class UserImpl implements User{@Overridepublic int age() {return 18;}@Overridepublic void sayHi(String name) {System.out.println("hello"+name);}
}
class UserProxy implements User{public User user;public UserProxy(User user){this.user=user;}@Overridepublic int age() {return 18;}@Overridepublic void sayHi(String name) {System.out.println("before");System.out.println("hello:"+name+",你的年龄是:"+user.age());System.out.println("after");}
}
public class Test10 {public static void main(String[] args) {User user=new UserImpl();UserProxy userProxy=new UserProxy(user);userProxy.sayHi("小白");}
}

5.静态代理代码

解释在代码后面,请耐心看完

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface School{void location();
}
class SchoolImpl implements School{@Overridepublic void location() {System.out.println("学校的位置");}
}
class SchoolInvocationHandler implements InvocationHandler{public Object target;public SchoolInvocationHandler(Object target){this.target=target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before");Object result=method.invoke(target,args);System.out.println("after");return result;}
}
public class Test13 {public static void main(String[] args) {School school=new SchoolImpl();SchoolInvocationHandler handler=new SchoolInvocationHandler(school);School schoolProxy=(School) Proxy.newProxyInstance(School.class.getClassLoader(),new Class[]{School.class},handler);schoolProxy.location();}}

首先,被代理的对象需要实现接口,如下图
在这里插入图片描述
为什么被代理对象要实现接口呢?
因为动态代理要求被代理对象实现接口主要是由Java动态代理机制的设计决定的。在Java中,动态代理是基于接口的,这意味着它使用接口来定义代理对象可以调用的方法集合。
然后,就创建一个调用器,这个所谓的调用器呢,你就可以当他是个工具,当代理对象去调用被代理对象的方法的时候,人家代理对象需要拿着这个调用器去调用方法,要不它调用不了,调用器的代码如下图,这个handler就是调用器
在这里插入图片描述
在这里插入图片描述
然后就创建代理对象,如下图红色圈,下图的绿色圈就是你需要被代理的类,这个类叫啥,你就把这里替换成相应的类名就行了
在这里插入图片描述
之后,当走了下图黄色圈的时候,也就是代理对象调用被代理类的方法的时候
在这里插入图片描述
这时候就相当于代理对象拿着调用器(handler),然后去找代理类,然后调用代理方法,然后走的是invoke,如下图,也就是说,当代理对象开始调用被代理类的方法的时候,就走调用器的invoke的方法
在这里插入图片描述
下面我来解释这三个参数
在这里插入图片描述
Object proxy:就代理对象自己,也就是schoolProxy,
Method method:是代理对象调用的方法,也就是location()方法
Object[] args:相当于location()方法里面的参数,我这个代码没有参数,如果有参数的话,比如location(int age,String name),就把这两个参数放到args这个数组,并且如果是基础数据类型,放到args这个数组就会变成包装类,也就是int变成Integer age
下面来解释下图红圈部分
在这里插入图片描述
method.invoke表示代理对象拿着调用器真正的去调用location方法了
target是被代理的对象
Object result代表的就是location()方法的返回值,如果没有返回值,那么object就是null

6.动态代理的底层

JDK动态代理的底层是通过java的反射机制实现的。
java的反射机制允许程序在运行时动态的获取类的信息(如成员变量,方法,构造函数等),并在运行时调用对象的方法或创建对象,如下源码所示
在这里插入图片描述
但是,动态代理除了可以依靠反射来实现之外,还可以使用字节码生成库来实现,字节码生成库允许我们在允许时生成字节码,从而创建代理对象,例如CGLib,它是一个开源的字节码生成库,它可以在运行时扩展java类并生成子类,从而实现动态代理的功能。

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

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

相关文章

FPGA-AXI4接口协议概述

假设我们要传一帧1080P的图片到显示屏显示,那么需要多大的储存空间呢? 一帧1080P的RGB565图像数据需要1920*1080*1633.1776Mb 存储空间 下图是ZYNQ-7000系列中Block RAM的大小: 可以看到最大存储空间的BRAM都不能存储一帧图片,那…

深入理解Vue.js中的nextTick:实现异步更新的奥秘

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

javascript实现解决浮点数加减乘除运算误差丢失精度问题【收藏点赞】

相信程序都会遇到这样的问题,有时需要在js上做运算合计等浮点数加减乘除,但会有些浮点数会有误差问题。下面用js来解决浮点数加减乘除运算误差丢失精度这个请 【收藏点赞】。 是程序都会在浮点数加减乘除上有误差问题,这是计算机二进制生成的…

GPU:使用阿里云服务器,免费部署一个开源大模型

前面提到CPU版本如何安装和部署ChatGLM,虽然能部署,但是速度和GPU比起来确实一言难尽。 然后找阿里云白嫖了一个服务器(省点用的话,不用的时候关机,可以免费用两个多月没问题),只要没有申请过 …

计算机网络—eNSP搭建基础 IP网络

目录 1.下载eNSP 2.启动eNSP 3.建立拓扑 4.建立一条物理连接 5.进入终端系统配置界面 6.配置终端系统 7.启动终端系统设备 8.捕获接口报文 9.生成接口流量 10.观察捕获的报文 1.下载eNSP 网上有许多下载eNSP的方式,记得还要下其它三个Virtual Box、Winpa…

【STA】SRAM / DDR SDRAM 接口时序约束学习记录

1. SRAM接口 相比于DDR SDRAM,SRAM接口数据与控制信号共享同一时钟。在用户逻辑(这里记作DUA(Design Under Analysis))将数据写到SRAM中去的写周期中,数据和地址从DUA传送到SRAM中,并都在有效时…

安卓studio安装

安卓studio安装 2024.3.11官网的版本(有些翻墙步骤下载东西也解决了) 这次写的略有草率,后面会更新布局的,因为截图量太大了,有需要的小伙伴可以试着接受一下哈哈哈哈 !(https://gitee.com/jiuzheyangbawjf/img/raw/ma…

mybatis如何打印出完整sql语句

分两步: 1. 在application.properties配置中添加配置项: mybatis-plus.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl logging.level.mapper文件的包路径DEBUG (示例: logging.level.com.test.biztest.service.dalDEBUG, com.test.biztest.service.d…

基于SpringBoot的农产品特色供销系统(蔬菜商城)

基于SpringBoot的农产品特色供销系统(蔬菜商城) 系统介绍 该系统使用Java、MySQL、Redis、Spring Boot和HTML等技术作为系统的技术支撑,实现了以下功能模块: (1)后台管理模块,包括权限、日志、…

MySQL数据库在Windows和Linux中由于大小写默认规则不同,出现大小写问题如何解决?

Windows和Linux差异:在Windows上,lower_case_table_names默认为1,而在Linux上,默认值通常为0。因此,在Linux上更改这个设置更常见,以确保与Windows环境的兼容性或实现特定的大小写敏感性需求。 操作系统的大…

[Flutter]自定义等待转圈和Toast提示

1.自定义样式 2.自定义LoadingView import package:flutter/material.dart;enum LoadingStyle {onlyIndicator, // 仅一个转圈等待roundedRectangle, // 添加一个圆角矩形当背景maskingOperation, // 添加一个背景蒙层, 阻止用户操作 }class LoadingView {static f…

【数据结构与算法】贪心算法题解(一)

这里写目录标题 一、455. 分发饼干二、56. 合并区间三、53. 最大子数组和 一、455. 分发饼干 简单 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这…

Visual Studio 2019重装vs2019打不开.netcore项目

无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBuild 的 17.4.0 版本。当前可用的 MSBuild 版本为 16.11.2.50704。请将在 global.json 中指定的 .NET SDK 更改为需要当前可用的 MSBuild 版本的旧版本。 无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBui…

【JAVA】Collections.sort()方法详解

一、简介 Collections.sort() 是 Java 集合框架(Java Collections Framework)中的一个静态方法,用于对列表(List)中的元素进行排序。此方法利用了 Java 的泛型机制,可以很方便地对各种类型的列表进行排序。…

使用gin框架,编写一个接收数据的api接口

功能:这里主要编写一个接口,将其json 数据存入对应的redis队列中,并统计每天的每小时请求数量 环境: go version go1.22.0 linux/amd64 平台 linux X64 步骤一 新建目录 命令如下: mkdir FormData 步骤二 新增…

当金蝶遇上BI,马上就能看到数据可视化效果

最近整理咨询内容时发现,很多企业用户在咨询时都会问是否有行业案例,究其原因时他们没用过BI数据分析,不知道BI可以做什么,能做到什么地步。其实,要知道这些东西还不简单,只需要注册奥威BI软件,…

CleanMyMac X 4.14.1中文版功能介绍及激活入口

细心的用户发现苹果Mac电脑越用越慢,其实这种情况是正常的,mac电脑用久了会产生很多的缓存文件,如果不及时清理会影响运行速度。macbook就会产生各种各样的垃圾文件,比如说残留的注册表或者无效的注册表,系统碎片以及毫无用处的文件等,这些的…

防御保护--第七次作业

题目 要求 在FW5和FW3之间建立一条IPSEC通道,保证10.0.2.0/24网段可以正常访问到192.168.1.0/24 过程 FW5 FW3

Cesium--基于材质旋转图片

材质部分的代码如下 // 自定义材质const customMaterial new Cesium.Material({translucent: true,fabric: {uniforms: {image:circle_img,speed:30.0,},source: czm_material czm_getMaterial(czm_materialInput materialInput){czm_material material czm_getDefaultMateri…

Python之Web开发中级教程----搭建Web框架一

准备环境:ubuntu,Python3.6.9 一、Web应用程序的原理 接收并解析HTTP请求,获取客户的请求信息->处理完成请求的业务逻辑->返回处理结果HTTP响应。 Web框架的架构是这样的: 基于python的web框架,如tornado、flask、webpy都是…