定义
代理模式:为其他对象提供一种代理以控制对这个对象的访问。
代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。
为什么要采用这种间接的形式来调用对象呢?一般是因为客户端不想直接访问实际的对象,或者访问实际的对象存在困难,因此通过一个代理对象来完成间接的访问。
静态代理模式
代理模式中的角色:
- 抽象主题角色(Subject):声明了目标对象和代理对象的共同接口,这样一来任何可以使用目标对象的地方都能用代理对象。
- 具体主题角色(RealSubject):称为委托角色或被代理角色。实现了目标对象。
- 代理主题角色(Proxy):也叫委托类、代理类。代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象。代理对象提供一个与目标对象相同的接口,以便可以在任何时候代替目标对象。
Subject
|
|
RealSubject
|
|
Proxy
|
|
来自客户端的调用
|
|
输出结果
|
|
从上面的例子可以看出来,代理对象将客户端的调用派给目标对象,在调用目标对象的方法之前和之后都可以执行特定操作。
动态代理模式
在实现动态代理模式之前,首先了解一下以下内容:
Jdk通过java.lang.reflect.Proxy包来支持动态代理,在Java中要创建一个代理对象,必须调用Proxy类的静态方法newProxyInstance,该方法的原型如下:
|
|
loader:类加载器,使用null使用默认的加载器
interfaces:接口或对象的数组,代理对象和真实对象共有的接口
handler:调用处理器,必须是实现了InvocationHandler接口的对象,其作用是定义代理对象中需要执行的具体操作。
InvocationHandler接口中只有一个方法invoke,它的作用就跟Runnable中的run方法类似,定义了代理对象在执行真实对象的方法时所希望执行的动作。其原型如下:
|
|
proxy:表示执行这个方法的代理对象
method:表示真实对象实际需要执行的方法
args:表示真实对象实际执行方法时所需的参数
Subject
|
|
RealSubject1 && RealSubject2 ……
|
|
Proxy
|
|
来自客户端的调用
|
|
动态代理模式通过使用反射,可以在运行期决定加载哪个类,避免了一个类对应一个代理的问题;同时,通过统一的invoke方法,统一了代理类对原函数的处理过程,使用动态代理很大程度上减少了重复的代码,降低了维护的复杂性和成本。