当前位置: 首页 > news >正文

Java基础:代理

目录

  • 一、什么是代理模式?
    • 1、代理模式的分类
    • 2、静态代理和动态代理的区别
  • 二、代理实现全过程
    • 1、静态代理
    • 2、动态代理

一、什么是代理模式?

代理模式:给定目标对象一个代理对象,并且由代理对象控制目标对象的引用。
“千万不要动别人的屎山代码”,或者,功能实现后不要修改代码。那如何在不动代码的前提下增加新的功能模块,代理可以实现这部分功能。
代理模式的主要作用:
1、避免直接访问目标对象,通过访问代理对象执行目标对象的方法。
2、增强目标对象的方法的功能。

1、代理模式的分类

代理模式分为静态代理动态代理
静态代理如下图:
在这里插入图片描述
一个代理类对应一个代理对象,并且一个代理对象对应一个目标对象,一个代理对象不能对应多个目标对象,不符合代理的一对一关系。
动态代理如下图:
在这里插入图片描述
一个代理类可以对应多个代理对象,一个代理对象对应一个目标对象,代理对象和目标对象的关系一一对应。

2、静态代理和动态代理的区别

静态代理:
代理类和目标类关系在编译时就确定。
需要编辑大量的代理类。
目标对象必须实现接口。
动态代理:
代理类和目标类的关系在运行时确定。
不需要手动编写代理类。
常用的是动态代理,因为不需要根据目标类自己重新的编辑大量的代理类,更加方便。

二、代理实现全过程

下面的过程将从一步一步从静态代理转变为动态代理的全过程,以方便更好的理解动态代理部分

1、静态代理

(1)构建目标类以及目标类当中的核心方法


public class L1 {public  void m1(){System.out.println("---L1");}
}

public class L2 {public  void m2(){System.out.println("---L2");}
}
public class L3 {public  void m3(){System.out.println("---L3");}
}

(2)构建代理类
首先以目标类1和代理类1入门,进行分析:

public class L {private L1 l1 = new L1();public  void runL1(){l1.m1();}
}

(3)Test测试类定义如下:

public class Test {public static void main(String[] args) {L l = new L();l.runL1();}
}

上面的情况为静态代理的过程。一个代理类对应一个目标类。实现不访问目标类,也可以执行目标类中的核心方法。
经过上面的情况,可能会有人疑惑,我如果把所有的目标类对应到一个代理类当中,不就可以一个代理类控制所有的目标类了吗?这不就是动态代理了吗?
即下面的情况:
在这里插入图片描述
也就是下面如图:
在这里插入图片描述
可以明显的看出来,每一个代理对象都可以对应所有的目标对象,不符合一对一的对应关系,因此上面的情况不属于代理。
静态代理的内存图如下:
在这里插入图片描述

2、动态代理

因为一个代理类对应多个目标类,但是一个代理对象对应一个目标对象。所以代理类中的目标对象需要根据对应的情况进行改变。
(1)因此代理类中的代码需要修改如下:
在这里插入图片描述
利用多态的方式进行接收传输进来的目标对象,可以实现根据对应的目标对象,创建出来对应的代理类。
(2)获得目标类当中的核心方法
需要用到 java.lang.relfect.Proxy,获得对应的目标类的接口。
将上面的运行目标类的方法修改为下面的情况(需要配合InvocationHandler使用):
下面代码的三个参数分别为:
1、利用反射获得的类加载器。
2、被代理对象实现的接口,这个也可以通过被代理对象获取。
3、 当我们在执行被代理对象的方法的时候,这个处理器就会被执行,当这个方法被执行的时候,会将被代理对象,方法,参数都传入进去

    public Object m1(){return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(),this);}

(3)重写接口InvocationHandler的方法
其中的三个参数都不需要自己填写,method为反射得到的,args是填写的参数,o是目标对象。

    @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {method.invoke(o,args);return null;}

(4)运行结果
目标类对应的接口如下:

public interface L1Inter {public void m1();
}
    public static void main(String[] args) {L1Inter l1 = (L1Inter) (new L(new L1())).LgetInter();l1.m1();}

利用L1对应的接口多态执行目标类的核心方法。

相关文章:

  • JavaScript篇:async/await 错误处理指南:优雅捕获异常,告别失控的 Promise!
  • Linux系统下安装mongodb
  • ensp的华为小实验
  • JavaSE核心知识点02面向对象编程02-06(泛型)
  • Metasploit 4.22.7:企业级渗透测试新突破
  • Open CASCADE学习|管道壳体生成
  • AI Coding的发展之路:从概念到改变世界的旅程
  • 学习黑客5 分钟深入浅出理解Linux Packages Software Repos
  • GMS 与非 GMS:有何区别?
  • 【工具记录分享】提取bilibili视频字幕
  • Lingma:云效 MCP 使用
  • 容器填充函数fill和memset对比总结
  • ospf实验报告
  • Java虚拟机的基本结构
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(18):条件形 文法
  • Gartner《Container发布与生命周期管理最佳实践》学习心得
  • libwebsockets:高性能跨平台WebSocket库实践指南
  • Vue基础(8)_监视属性、深度监视、监视的简写形式
  • 《全球短剧正版授权通道,助力平台出海与流量变现》
  • HashMap中put()方法的执行流程
  • 交涉之政、交涉之学与交涉文献——《近代中外交涉史料丛书》第二辑“总序”
  • 道指跌逾100点,特斯拉涨近5%
  • 三大猪企4月生猪销量同比均增长,销售均价同比小幅下降
  • 稳住外贸基本盘,这个中部大省出手了
  • 丰田汽车:美国关税或导致4、5月损失1800亿日元,新财年净利润下滑三成
  • 教育部、国家发改委联合启动实施教师教育能力提升工程