Java代理模式
The trees, like the longings of the earth, stand atiptoe to peep at the heaven.
群树如表示大地的愿望似的,踮起脚来向天空窥望。
静态代理
假设现在有一个人(person接口),他的名字叫A(class A implement person),小A 40岁了必须要找对象,但是呢自己比较害羞不好意思开口,这样就需要一个媒婆来帮他找对象(MeiPo 代理类),至此就是静态代理模式,下面我们用代理来实现下:
Class Person
1 |
|
Class A
1 |
|
Class Meipo
1 |
|
Main
1 |
|
静态代理模式总结
- 真实对象和代理对象都要实现同一接口
- 代理对象要代理真实角色
好处:
- 代理对象可以做很多真实对象做不了的事情 、
- 真实对象可以专注做自己的事情
缺点:
一个真实角色会产生一个代理角色
动态代理
实现代理对象的步骤
- 创建接口,定义目标类要完成的功能
- 创建目标类,实现接口
- 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
- 调用目标方法
- 增强功能
- 使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型
- 动态代理角色和静态代理角色一样
- 动态代理的代理类时动态生成的,不是我们直接写好的
- 分为两类
- 基于接口的动态的代理:基于JDK的动态代理
- 基于类的动态代理:cglib
- java字节码实现:javasist
基于JDK的动态代理
JDK提供了java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy类,这两个类相互配合
- Proxy:代理
- InvocationHandler:调用处理程序
例
上面的静态代理是每来一个人就创建一个媒婆代理他,这样的话工作过于繁琐,这时我们为何我开一个媒婆公司呢?将找对象的人交给媒婆公司,让媒婆公司创建媒婆代理他传宗接代的任务!
Class B
目标接口的实现类,也就是接下来的目标类
1 |
|
findLove
目标类中目标方法
媒婆 改为 媒婆公司:Class MeipoCompany
代理类
1 |
|
在invoke()方法中,我们没有创建对象,所以,我们使用method.invoke
两个参数:
- 对象,这个对象是动态的,不是固定的,所以我们需要传入进来,可以通过调用该类的构造方法
setTarget()
进行传入 - 参数,调用方法的参数,即args
Main
1 |
|
1
2
3
4
5
6
7
8
9
10
//1. 创建目标对象
Person B = new XiaoB();
//2. 创建 InvocationHandler 对象
InvocationHandler handler1 = new MeipoCompany(B);
//3.创建代理对象
Person proxy = hander.getInstance(handler);
Person proxy = (Person)Proxy.newProxyInstance(B.getClassLoader(), B.getInterfaces(), handler1)
System.out.println("代理类:"+B.getClass());
//4.通过代理执行方法
proxy.findLove();这段代码中不需要
MeipoCompany
中有getInstance
方法,直接在main类中实现,等价于A的动态代理
这里调用方法时,就会自动跳转到invoke方法,将方法名与参数传递给invoke中的method.invoke方法
InvocationHandler
实现InvocationHandler,重写invoke方法
处理代理实例,并且返回结果
1 |
|
invoke
表示代理对象要执行的功能代码,代理类要完成的功能就写在invoke中。
调用目标方法,执行目标方法的功能
功能增强,在目标方法调用时,增加功能
参数
Object proxy
jdk创建的代理对象,无需赋值
Method method
目标类中的方法,jdk提供,无需赋值
Object[] args
目标类中方法的参数,jdk提供,无需赋值
Method类
:表示方法的类,确切的说就目标类中的方法
作用:通过Method可以执行某个目标类的方法,method.invoke()
method.invoke(目标对象,方法的参数)
Proxy类
核心对象,创建代理对象
之前的创建对象都是new类的构造方法,现在我们是使用Proxy类的对象,代替new的使用.
静态方法newProxyInstance
1 |
|
作用:创建代理对象,等同于静态代理中的new
参数
ClassLoader loader
类加载器,负责向内存中加载对象,使用反射获取对象的ClassLoader
是目标对象的类加载器
Class<?>[] interfaces
是接口,目标对象所实现的接口,也是反射获取的
InvocationHandler h
是我们自己写的,代理类要完成的功能
返回值:就是目标对象的代理对象
- 本文作者:bobo
- 本文链接:https://boyolo.github.io/article/21345.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!