0
点赞
收藏
分享

微信扫一扫

Spring入门理解(八)静态代理模式和动态代理模式详解

niboac 2022-04-13 阅读 81

目录

1 静态代理模式

1.1 案例一:出租房屋

1.1.1 无代理模式

在这里插入图片描述

1.1.2 有代理模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1.3 代理模式代码分析

分析1:
在这里插入图片描述

在这里插入图片描述
为何使用组合的方式获取Host?
为何不使用继承获取Host?

分析2:
Clicent.java中为何写了两种获取proxy对象?有何区别?

1.2 案例二:增删改查

在这里插入图片描述

1.2.1 无代理模式

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
那如果有1万个不同的增删改查,岂不是得修改源代码1万次,实际的项目中,该文件关联许多其他的文件,你一个实习生一过来就修改人家公司源代码,这是绝对不允许的,那怎么办呢?设置一个代理就可以了

1.2.2 代理模式

在这里插入图片描述
在这里插入图片描述

1.2.3 代理模式代码分析

Proxy.java 文件中,熟悉的套路

  • 组合方式获取实现类
  • 创建 set方法 或者 有参构造的方法
  • 重写接口

2 动态代理模式

2.1 案例一: 代码体验

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 逻辑分析

这就是动态的初步理解!


2.3 代码分析

经过前面的梳理,我们从上帝的视角出发,知道了动态代理大概是怎么一回事:就是调用系统封装好的一个Proxy代理类,实现代理功能嘛。接下来我们具体分析一下代码,看看是简单的调用吗?为什么要这样调用,原理是什么?带着等等问题我们往下分析

在这里插入图片描述
在这里插入图片描述
这个图大致表达了各个方法之间的联系


思考 : 二
为什么可以跳转到public Object invoke()?

利用了反射,怎么利用的是底层逻辑暂时不去深究,但是在这里稍微点一下
我们可以打两个断点
在这里插入图片描述
进入invoke方法看一下,发现进入了反射类中,并且成功传入了接口Rent
在这里插入图片描述


思考 : 三

  1. Proxy.newProxyInstance(类加载器, 代理接口,一个InvocationHandler对象)的三个参数是什么意思?
    此处的类加载器:类.getClass().getClassLoader()
    关于类加载器的介绍在Java深渊处的秘密(第二遍总结:通俗解释反射原理).在这里插入图片描述
  2. 此处代理接口:类.getClass().getInterfaces()
    类.getClass就可以获得类对象
    在这里插入图片描述
  3. 一个InvocationHandler对象:this
    为何传的参数是this呢-------因为this代表的是InvocationHandler接口实现类本身,并不是真实的代理对象。proxy参数是代理类的真实代理对象
    一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用。


思考:四
public Object invoke(Object proxy, Method method, Object[] args)


Java中InvocationHandler中第一个参数Proxy详解

  • 讲解前我们先列一下我们要说明的问题
  1. proxy代表什么意思
  2. proxy参数怎么用及什么时候用
  3. proxy参数运行时的类型是什么
  4. 为什么不用this代替proxy

  • proxy代表什么意思

    proxy是真实对象的真实代理对象,invoke方法可以返回调用代理对象方法的返回结果,也可以返回对象的真实代理对象(com.sun.proxy.$Proxy0)。

  • proxy参数怎么用及什么时候用

    proxy参数是invoke方法的第一个参数,通常情况下我们都是返回真实对象方法的返回结果,但是我们也可以将proxy返回,proxy是真实对象的真实代理对象,我们可以通过这个返回对象对真实的对象做各种各样的操作

  • proxy参数运行时的类型是什么


    上面我们已经打印出了proxy的类型是:com.sun.proxy.$Proxy0真实的代理对象

  • 为什么不用this替代


    因为this代表的是InvocationHandler接口实现类本身,并不是真实的代理对象。

2.4 案例二:代码体验

如法炮制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.5 案例二:功能拓展

模仿刚才的代码,我们再一次成功实现了使用动态代理
接口定义了四个方法:增删改查

接下来我们拓展一下:
UserService定义了增删改查的方法,代理帮助实现了增删改查
但是代理自己还想增加一个输出日志(打印调用了哪个方法)的功能。这属于私自拓展的,(规范要求)不能修改接口和实现类中原来的代码,于是我们只能在代理类中进行操作

具体怎么操作往下看
在这里插入图片描述
回顾一下静态代理中,我们如何在代理类中实现增加输出日志的功能
在这里插入图片描述
在动态代理中
不清楚method.getName()的建议参考Java深渊处的秘密(第二遍总结:通俗解释反射原理).
在这里插入图片描述
在这里插入图片描述

至此Spring中静态代理动态代理的简单应用在这块就介绍完了!

举报

相关推荐

0 条评论