一简介
代理是英文 Proxy 翻译过来的。我们在生活中见到过的代理,大概最常见的就是朋友圈中卖面膜的同学了。
她们从厂家拿货,然后在朋友圈中宣传,然后卖给熟人。
UML图
要点:
1. 用户只关心接口功能,而不在乎谁提供了功能。上图中接口是 Subject。
2. 接口真正实现者是上图的 Proxied,但是它不与用户直接接触,而是通过代理。
3. 代理就是上图中的 Proxy,由于它实现了 Subject 接口,所以它能够直接与用户接触。
4. 用户调用 Proxy 的时候,Proxy 内部调用了 Proxied。所以,Proxy 是中介者,它可以增强 Proxied 操作。
代理又分为静态代理与动态代理。
二 静态代理
为什么叫做静态呢?因为它的类型是事先预定好的,在程序编译时,就能知道被代理角色是谁,比如下面代码中的 Badstudent 这个类。
下面我举一个好学生代替坏学生完成作业的例子。
1.首先定义一个通用的接口Student,规定学生要做什么。
2.然后定义一个好学生GoodStudent 实现接口,这个类作为真正的业务实现者,(代理者)
3.最后再定义一个坏学生,通过好学生完成他 的作业 (代理者)
测试
结果
做作业
看书
背单词
静态代理的总结
优点:可以做到不对目标对象进行修改的前提下,对目标对象进行功能的扩展和拦截。
缺点:因为代理对象,需要实现与目标对象一样的接口,会导致代理类十分繁多,不易维护,同时一旦接口增加方法,则目标对象和代理类都需要维护。
代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类
三 动态代理
动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能。
三要素:
1 代理接口:规定被代理的类的功能
2. 具体实现类: 实现代理接口,作为被代理者
3 具体执行者: 实现 InvocationHandler 接口 ,作为代理者
下面我们定义一个柜台卖酒的例子,可以理解为原来是散户卖酒,现在通过柜台代理卖酒
具体实现:
1.定义代理接口
2.具体实现类
卖茅台酒
卖剑南春
3.代理者 柜台A
测试
结果
这里是:GuiTaiA
卖茅台酒
消费结束
------------
这里是:GuiTaiA
剑南春
消费结束
语法解析
Proxy
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
loader 自然是类加载器 (目标类加载器)
interfaces 代码要用来代理的接口(目标类接口)
h 一个 InvocationHandler 对象 (实际执行类)
InvocationHandler
public interface InvocationHandle
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
- proxy 代理对象
- method 代理对象调用的方法
- args 调用的方法中的参数