Java动态代理

news/2024/11/28 11:42:10/

一. 什么是动态代理

  • 假设Student里面有一个吃饭的eat方法,那么现在我要给这个方法去增加其他的功能,比如说吃饭之前,要去拿筷子,要去盛饭,按照以前所学,我们只能把这两段代码都写在eat方法当中,那此时直接去修改代码,是叫做侵入式修改。

  • 在以后在一个成熟的项目当中,我们一般很少会这么去干。
  • 那么问题来了,我现在又不能去修改原有的代码,又要去增加额外的功能,那这个时候我该怎么办呢?
  • 此时我们就得去找一个代理,什么是代理,说白了就是中介公司。
  • 代理会帮你先去做拿筷子和盛饭这两个准备工作,等真正的吃饭了再去调用Student里面的方法去吃饭,这个呢其实就是动态代理。

1.为什么需要代理呢?

  • 代理可以无侵入式的给对象增强其他的功能。
  • 当调用者去调用对象中的方法的时候,其实呢不是直接通过对象去调用,而是先去调用代理中的方法,代理会做一些准备工作,然后呢再由代理去调用对象中的方法,是有这样的一个过程

 二. 程序为什么需要代理?代理长什么样?

程序为什么需要代理?

  •  说白了就是因为如果对象任务自己身上干的事情太多了,就可以通过代理转义部分的职责。

那么中介派出的这个代理它是长什么样子的呢?

  • 代理里面就是对象要被代理的所有的方法
  • 在代码当中代理长什么样子,说白了就是代理的里面可以写什么样的方法。
  • 代理长什么样子,其实是跟对象差不多的。
  • 对象要有什么方法想要被代理,那么代理呢也要有对应的方法,只不过方法里面干的事情是不太一样的,代理它会先把准备工作做完,然后再去调用对象中的方法。
  • 代理是通过接口去知道对象想要代理的方法,在这个接口里面所有的方法就是我们想要代理的方法。
  • 左边的代理和右边的对象都要去实现中间的这个接口才是可以的!

  1.  为什么需要代理?
  • 代理可以无侵入式的给对象增强其他的功能。
  1. 代理长什么样?
  • 代理里面就是对象要被代理的所有的方法。
  1. Java通过什么来保证代理的样子?
  • Java通过接口保证代理的样子,对象和代理需要实现同一个接口,接口中就是被代理的所有的方法。

 三. 如何为Java对象创建一个代理对象

 

package com.gch.d10_dynamic_proxy;/**定义大明星类:模拟对象*/
public class BigStar implements Star{private String name;public BigStar() {}public BigStar(String name) {this.name = name;}/*** 唱歌* @param name:歌曲的名字* @return:"谢谢"*/@Overridepublic String sing(String name){System.out.println(this.name + "正在唱" + name);return "谢谢";}/**跳舞*/@Overridepublic void dance(){System.out.println(this.name + "正在跳舞!");}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}public String toString() {return "BigStar{name = " + name + "}";}
}
package com.gch.d10_dynamic_proxy;/**接口:接口当中定义的是对象所有想要被代理的方法(抽象方法)我们可以把所有想要被代理的方法定义在接口当中*/
public interface Star {/*** 唱歌* @param name:歌曲名*/public abstract String sing(String name);/**跳舞*/public abstract void dance();
}
package com.gch.d10_dynamic_proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** 代理类* 类的作用:创建一个代理*/
public class ProxyUtil {/*** 方法的作用:给一个对象,去创建一个代理对象* 方法的返回值类型直接写接口的类型,因为我们的代理也是要去实现接口的* @param bigstar:形参:被代理的明星对象* @return  返回值:给明星创建的代理对象*/public static Star createProxy(BigStar bigstar){/***  java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:*         public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)*         参数一:用于指定用哪个类加载器,去加载生成的代理类   是类加载器把类的字节码文件加载到内存当中的*         参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法*         参数三:用来指定生成的代理对象要干什么事情*/Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), // 参数一:用于指定用哪个类加载器,去加载生成的代理类new Class[]{Star.class} // 参数二:指定接口,这个就表示我们生成的这个代理,也就是中介,它可以代理Star这个接口里面所有的方法, new InvocationHandler() { // 参数三:用来指定生成的代理对象要干什么事情@Override/*** 用来指定生成的代理对象要干什么事情 invoke:调用* 参数一:表示代理的对象,重点看参数二和参数三* 参数二:要运行的方法  sing,dance...* 参数三:调用sing方法时,传递的实参*/public 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;}
}
package com.gch.d10_dynamic_proxy;/**需求:外面的人想要大明星唱一首歌1.获取代理对象代理对象 = ProxyUtil.createProxy(大明星的对象);2.再调用代理的唱歌方法代理对象.唱歌的方法("只因你太美");*/
public class Test {public static void main(String[] args) {// 1.创建对象BigStar bigStar = new BigStar("鸡哥");// 2.获取代理的对象  proxy:代理Star proxy = ProxyUtil.createProxy(bigStar);// 3.调用唱歌的方法String result = proxy.sing("只因你太美");System.out.println(result);// 4.调用跳舞的方法proxy.dance();}
}

 


http://www.ppmy.cn/news/41786.html

相关文章

golang指针相关

指针相关的部分实在是没有搞太明白&#xff0c;抽时间来总结下。 1.指针相关基础知识 比如现在有一句话&#xff1a;『谜底666』&#xff0c;这句话在程序中一启动&#xff0c;就要加载到内存中&#xff0c;假如内存地址0x123456&#xff0c;然后我们可以将这句话复制给变量A&…

CentOS Ubuntu Debian三个linux的异同对比

Linux有非常多的发行版本&#xff0c;从性质上划分&#xff0c;大体分为由商业公司维护的商业版本与由开源社区维护的免费发行版本。 商业版本以Redhat为代表&#xff0c;开源社区版本则以debian为代表。这些版本各有不同的特点&#xff0c;在不同的应用领域发挥着不同的作用&…

执行命令行程序测试自动化

这几天有一个小工具需要做测试&#xff0c;是一个命令行工具&#xff0c;这个命令行工具有点类似mdbg等命令行工具&#xff0c;即程序运行后&#xff0c;在命令行等待用户敲入的命令&#xff0c;处理命令并显示结果&#xff0c;再继续等待用户敲入新的命令。 原来的测试用例都…

ROS开发之如何制作launch启动文件?

文章目录0、引言1、Launch文件语法2、Launch示例0、引言 笔者因研究课题涉及ROS开发&#xff0c;学习了古月居出品的ROS入门21讲&#xff0c;为巩固launch的知识&#xff0c;本文将ROS的launch启动文件制作一讲内容进行总结。launch文件通过XML文件实现多节点的配置和启动&…

那些警示良言——鲁迅

鲁迅的警示言 1、中国人的性情是总喜欢调和折中的&#xff0c;譬如你说&#xff0c;这屋子太暗&#xff0c;须在这里开一个窗&#xff0c;大家一定不允许的。但如果你主张拆掉屋顶他们就来调和&#xff0c;愿意开窗了。 ——《无声的中国》一九二七年 2、我每看运动会时&…

如何在windows/linux下启动OpenOffice

上面一篇文章使用openOffice来实现预览word、excel、pdf、txt等的功能时&#xff0c;发现openOffice没有启动&#xff0c;也怕有些同学安装后不会启动&#xff0c;所以便写下这一篇文章&#xff0c;来为大家说明如何启动openOffice&#xff0c;上一篇讲的如何下载安装openOffic…

2023年咸阳市《网络搭建与应用》专业技能大赛试题

竞赛说明 竞赛内容发布“网络搭建与应用”赛项竞赛共分三个部分,其中: 第一部分:网络搭建及安全部署项目(500分) 第二部分:服务器配置及应用项目(480分) 第三部分:职业规范与素养(20分) 竞赛注意事项禁止携带和使用移动存储设备、计算器、通信工具及参考资料。请根据…

【Linux】一篇文章, 掌握Linux进程信号

文章目录进程信号介绍进程信号进程信号的处理signal() 捕捉信号用户层产生进程信号的方式键盘产生进程信号系统调用产生进程信号kill()raise()abort()软件条件产生进程信号硬件异常产生进程信号除0 和 越界访问、野指针 如何产生相应信号除0越界访问、野指针core dumpcore 文件…