java动态代理_JAVA动态代理

JAVA中对类进行增强的方式大致有三种

1、继承;

2、装饰者;

3、代理模式。

继承是最基础的,也是面向对象的三大基本特征之一。优点是逻辑简洁清晰,缺点是目标对象和增强部分固定,高度耦合。

而装饰者模式对继承进行的改善。“是你还有你,一切依赖你“:与被增强对象继承同一父类且内部持有被增强对象实例。运行期间对对象进行增强,对目标对象进行了解耦,但增强内容是不能改变的。

代理模式进一步对增强内容进行的解耦,使其更加灵活。

(1)静态代理:实现较为简单,具体可以理解为编写一个代理类,实现目标对象相同接口,并在内部维护一个对象的引用。然后对增强方法进行复写。

注意区分:静态代理和装饰者模式比较像,但静态代理是编译时期就进行了对象增强,而装饰者模式则是在运行期间增强。

(2)动态代理:在运行时创建一个实现某些给定接口的新类(也称"动态代理类")及其实例。

使用动态代理首先要熟悉两个类:java.lang.reflect包下的Proxy、InvocationHandler

Proxy:

835126d5eb78bf41aecebc8ade5cb2b1.png

Proxy中有一个静态方法newProxyInstance,可以通过三个参数——类加载器、接口、和InvocationHandler来返回一个代理对象实例。

InvocationHandler:

8cbf0c4d8f50c9425282ed5bb40773bd.png

InvocationHandler是一个接口,只有一个函数invoke。其中包含了三个参数,从名字看得出来第二参数是方法对象。

newProxyInstance实验:

类加载器:

d28baf92aa209157bd143d50a80fae34.png

接口:

6df3ee2568e74f482404c5ac90b304dd.png

InvocationHandler:

e7767dfa7117c78702ceee7130e50020.png

结果:

ba4b54f51fcdfc4c7ea9a03b883c98dd.png

目前结论:

1. 调用newProxyInstance会生成一个包含$Proxy7的一个代理类;

2. 使用接口方法会调用InvocationHandler的invoke。

InvocationHandler参数实验:

interfaceA中添加有变量的函数声明:

a887a8907212dafac5352c287c4d7e91.png

再到InvocationHandler的invoke方法复写

96b4584b3205a52eb60d42c2ef20b446.png

05de6046df0838e77c21d45851df4b36.png

结果:

b9393d3b056b1206fd72a6082987bf79.png

可以得出结论:InvocationHandler中第一个参数是代理类、第二个参数是方法、第三个参数是方法中传入的参数。

小结:proxy的newProxyInstance方法可以通过类加载器、接口、和InvocationHandler三个参数创建一个实例对象。对象可以根据接口类型进行多态转换,调用方法。调用方法时调用InvocationHandler中的invoke方法。

目的:对目标对象进行增强,所以目标对象也要传入。

新建一个Person对象,实现A接口

b70384bb3747585a85c136c3add84010.png

动态代理中传入Person的实例,且在invoke中调用

952ae14703f8d6a9267db5305bb29e74.png

进行调用

70b29d7cd0aad5aee0e2d3978cf471aa.png

结果

c4154bad4b6a188a2c07baf2849c1712.png

目前问题: 增强方法是固定的,修改需要更改内部代码。

解决方法:将增强方法方法传参。

第一步:预设增强方式分为前置增强和后置增强,创建beforeAdvice和afterAdvice两个接口。

0304a31a7f2518f07925a429036f194a.png

使用工厂模式来返回增强的对象,其中工厂内需要beforeAdvice和afterAdvice还有目标对象三个参数。

第二步:创建ProxyFactory的类,里面包含beforeAdvice、afterAdvice、targetObject

abb4f3aec647ba8a0a76536cd5f39494.png

第三步:写createObject函数返回一个增强对象,

6e83330634750b8aa8ea4448cc0b5eca.png

测试:

6ee30d8eeb4754bc8c85ae3745e6199e.png

结果:

c6cfc2766ad804cfde922009387c3017.png

此时就可以把增强方法和目标函数进行了解耦,动态返回了代理对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值