动态代理详解

news/2024/5/6 21:20:41/文章来源:https://blog.csdn.net/hc1285653662/article/details/127199791

想要更加透彻的理解动态代理,首先要熟悉下静态代理

一、静态代理

总结来说:目标类和代理类实现了相同的接口在代理类中依赖了目标类,代理类的方法中调用了目标类的方法,并做了一些增强性的工作。

1、实现静态代理(demo)

要求,在某个类执行类中的方法时,上下文添加一些日志记录

1)定义接口

public interface Calculate {int add(int num1,int num2);
}

2)定义委托类

public class Calculator implements Calculate {@Overridepublic int add(int num1, int num2) {System.out.println(num1 + "+" + num2 + "=" + num1 + num2);return num1 + num2;}
}

3)定义代理类

public class CalculatorWithLog implements Calculate {private Calculator calculator;public CalculatorWithLog(Calculator calculator) {this.calculator = calculator;}@Overridepublic int add(int num1, int num2) {System.out.println("add前添加一点日志");int sum = calculator.add(num1, num2);System.out.println("add后添加一点日志");return sum;}
}

4)测试

 public static void main(String[] args) {Calculator calculator = new Calculator();CalculatorWithLog calculatorWithLog = new CalculatorWithLog(calculator);calculatorWithLog.add(1, 2);}

在这里插入图片描述

2、静态代理的缺陷

  • 程序员要手动为每一个目标类编写对应的代理类。如果当前系统已经有成百上千个类,工作量太大了
  • 当接口改变时,所有的代理类都需要进行相应的变化,太过于耦合
    所以,现在我们的努力方向是:如何少写或者不写代理类,却能完成代理功能?

二、动态代理

参考B站视频:https://www.bilibili.com/video/BV1HZ4y1p7F1?p=7&vd_source=7f24cfc4e2c729f062d4a78d958bfcdf

动态代理指的是:在程序的执行过程中,使用jdk的反射机制,创建代理对象,并动态的指定代理的目标类

动态代理的实现方式常用有两种:
- 使用JDK代理
- 通过CDLIB代理

1、jdk动态代理

jdk动态代理是基于Java的反射机制实现的,使用jdk反射包下的Proxy和InvocationHandler实现代理对象的动态创建
jdk动态代理要求目标对象必须实现接口

1)InvocationHandler接口

接口中就一个方法 :invoke()
你的代理类要完成的功能就写在invoke()中

代理类需要完成的功能:

  • 调用目标类的方法
  • 功能增强,在目标方法调用时,增加功能

方法原型:
Object proxy:jdk创建的代理对象,无需赋值
Method method:目标类中的方法
Object[] args:目标类中方法的参数
public Object invoke(Object proxy, Method method, Object[] args)

2)Method类

通过Method可以执行某个目标类的方法

3)proxy类

是最核心的一个类,使用静态方法 newProxyInstance() ,创建代理对象
方法原型:
ClassLoader loader:类加载器,负责向内存中加载对象(需要使用目标对象的类加载器)
Class<?>[] interfaces:目标对象实现的接口 InvocationHandler h:我们自己写的代理类需要实现的功能 返回值就是代理对象 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)

4)动态代理的实现步骤

  • 创建接口,定义目标类要完成的功能
public interface Calculate {int add(int num1,int num2);
}
  • 创建目标类,实现该接口
public class Calculator implements Calculate {@Overridepublic int add(int num1, int num2) {System.out.println(num1 + "+" + num2 + "=" + (num1 + num2));return num1 + num2;}
}
  • 创建 InvocationHandler 接口的实现类,在invoke()方法中完成代理类的功能
public class MyInvocationHandler implements InvocationHandler {private Object target = null;//动态代理,目标对象是活动的,不是固定的,需要传入进来public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object res = method.invoke(target, args);System.out.println("代理对象中进行功能增强....");return res;}
}
  • 使用proxy类的newProxyInstance()方法,创建代理对象,并把返回值转成接口类型
public class Test {public static void main(String[] args) {//1、创建目标对象Calculator calculator = new Calculator();//2、创建invocationHandler对象InvocationHandler invocationHandler = new MyInvocationHandler(calculator);Calculate proxyInstance =(Calculate) Proxy.newProxyInstance(calculator.getClass().getClassLoader(), calculator.getClass().getInterfaces(),invocationHandler);proxyInstance.add(1, 3);}
}

5)jdk动态代理的执行流程

2、cglib动态代理(了解)

cglib是第三方的工具库,可以创建代理对象。cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类中的方法,实现功能的修改
(要求目标类不能是final,且目标类的方法不能是final修饰的)
在这里插入图片描述

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

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

相关文章

ROS|乌龟TF变换案例分析

1. 相关源码内容 1.1 turtle_df_demo.launch <launch><!-- Turtlesim Node--><node pkg"turtlesim" type"turtlesim_node" name"sim"/><node pkg"turtlesim" type"turtle_teleop_key" name"tel…

如何快速创建 GCDW 实例

GCDW 实例需云用户注册 GCDW 租户成功后&#xff0c; GBASE 云服务系统给租户分配独 立的实例&#xff0c; 同时创建租户的数据库根用户&#xff0c; 根用户即为该实例的超户&#xff0c; 拥有该实例 的最高权限&#xff0c; 租户可以通过根用户登录自己的实例管理数据&#xf…

Centos7 单机单网卡 RDO 安装 OpenStack

文档 OpenStack 涵盖太多知识量&#xff0c;总是找不到一个称心的官方文档 OpenStack Installation Guide for Red Hat Enterprise Linux and CentOS 这个是中文版的&#xff0c;但是 UPDATED: 2017-06-12 11:14 &#xff0c;很古老了&#xff01;基本概念和思想还是一样的 h…

SiO2/罗丹明B荧光杂化纳米微球/硅钼比核壳结构二氧化硅微球钼酸钙荧光粉的性能

SiO2/罗丹明B荧光杂化纳米微球性能制备&#xff1a; 在甲苯存在下的反相微乳液体系中,将γ-缩水甘油醚氧丙基三甲氧基硅烷(KH560)与罗丹明B进行预反应&#xff1b;再与正硅酸乙酯( TEOS)经原位溶胶-凝胶反应,制备SiO2/罗丹明B荧光杂化纳米微球.通过FTIR、UV-Vis、TEM、TG和光致…

聚焦 | 电力行业国产操作系统迎来大市场,麒麟信安积极承接发展新机遇

近年来&#xff0c;针对信息安全的外部环境不确定性加剧&#xff0c;作为关系到国计民生的电力行业&#xff0c;加速了自主创新的步伐。 从2009年起&#xff0c;电力行业就开始采用拥有自主核心技术的软硬件设施&#xff0c;到如今&#xff0c;整个电力行业已普遍完成了调度自动…

4.<tag-排序和TopK问题的三种典型解法>补充: 面试题 17.14. 最小K个数 + lt.215-数组中的第K个最大元素 dbc

面试题 17.14. 最小K个数 [案例需求] TopK问题很普遍, 解题套路也很简单, 无非就是排序, 运用最基础的排序(如Array.sort(nums))复杂度为nlogn, 或者使用堆, 复杂度为nlogk, 或者在快排的基础上进行减治 详细参见此文: 点我 [思路分析一, 直接排序] 对原数组从小到大排序后取出…

毕业设计 深度学习 机器视觉 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过…

Airflow学习笔记

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 项目中解决的问题 使用airflow调度hive脚本跑批任务 视频教程上整理知识点 学习视频&#xff1a;https://www.bilibili.com/video/BV1V7411K7Gy?p40&vd_sourceb002288652bae647c598ddf77f79a7b8 Airflow基本概念 Airfl…

【VUE2开发20221004】-day1.0

目录测试案例1&#xff1a;Vue常见指令&#xff1a;1、插值表达式2、v-bind指令v-bind指令注意事项简写v-bindv-bind属于单向绑定&#xff08;JS修改->HTML修改&#xff09;3、v-model指令v-model常用标签4、v-for指令5、v-on事件前端开发教程链接 vuejs官方教程 框架&…

刷题笔记-栈帧

例题1 阅读如下C代码片段&#xff08;其中Y表示代码指令地址&#xff09;&#xff1a; void overflow(char* pShellcode, int iLen) { Y1&#xff1a;char buffer[8]; Y2: memcpy(buffer, pShellcode, dwLen); Y3: „„ } Y4: int main() { Y5: „„ Y6: overflow("123…

多处理机的基本概念

本文内容是作者在进行计算机组成原理复习的时候&#xff0c;用王道的视频做笔记或者保存图的内容。后续如果看了其他书或者有其他理解会进行增加内容。 SISD&#xff08;单指令流数据流&#xff09; 特性&#xff1a;各指令序列只能并发、不能并行&#xff0c;每条指令处理一…

Prophet算法

Prophet简介 Prophet是FaceBook公司在2017年开源的一款时间序列建模工具。Prophet的方法是将时间序列看成是关于t的一个函数&#xff0c;用你和函数曲线的方法进行预测&#xff0c;所以这和传统的时间序列模型有本质上的区别&#xff0c;他更倾向于机器学习的建模方式。 Prop…

PO/PI

典型集成场景 PI总体架构

浅学设计模式(二)

目录&#xff1a; &#xff08;1&#xff09;工厂模式 简单工厂&#xff1a; 工厂方法模式&#xff1a; &#xff08;2&#xff09;抽象工厂模式 &#xff08;1&#xff09;工厂模式 简单工厂&#xff1a; 原来的方式使用new&#xff1a; 需要关心细节&#xff0c;如何创建对…

独家分享 圆梦阿里之后,我得到了这份SpringCloud Alibaba源码文档

Spring Cloud Alibaba为分布式应用开发提供了一站式解决方案。它包含开发分布式应用程序所需的所有组件&#xff0c;可以轻松地使用Spring Cloud开发应用程序。 使用Spring Cloud Alibaba&#xff0c;只需添加一些注解和少量配置&#xff0c;即可将Spring Cloud应用连接到Alib…

Spring 4 IOC 相关内容 4.2 bean 实例化 3 实例工厂实例化

Spring 【黑马程序员2022新版SSM框架教程_SpringSpringMVCMaven高级SpringBootMyBatisPlus企业实用开发技术】 4 IOC 相关内容 文章目录Spring4 IOC 相关内容4.2 bean 实例化4.2.5 实例工厂与FactoryBean4.2.6 bean 实例化小结4.2 bean 实例化 4.2.5 实例工厂与FactoryBean …

Python学习笔记(四)——字符串与文本处理2

目录 字符串函数大合集 两端删除函数strip() 删除空白字符 删除两端指定字符 右端删除函数rstrip() 左端删除函数 字符串对齐 返回指定宽度字符串center() 原字符串居中对齐、左对齐、右对齐 字符串开始或结束符判定startswith()、endswith() 内置函数eval()&#x…

web期末作业设计网页 html+css+js制作非物质文化遗产坝漆国漆 2页

&#x1f329;️ 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f482; 作者主页: 【进入主页—&#x1f680;获取更多源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;HTML5网页期末作业 (1000套…

鉴源论坛丨民用飞机机载软件是如何表明适航符合性的

作者 | 蔡喁 上海控安可信软件创新研究院副院长 版块 | 鉴源论坛 观擎 01 机载软件的基本特征 机载计算机在现代飞机各组成部分中占有举足轻重的位置&#xff0c;是现代航空电子系统的基础和核心&#xff0c;其研制、生产和应用水平已成为衡量飞机先进性的重要标志。机载计…

【面试题】Java基础 2

若你困于无风之地&#xff0c;我将为你奏响高空之歌 文章目录一、int 和 Integer 对象1. int 和 Integer 对象的区别2. 变量比较问题&#xff1a;二、反射1. 反射机制定义2. 反射的使用步骤3. 一个小栗子4. 反射的应用一、int 和 Integer 对象 1. int 和 Integer 对象的区别 …