概述
-
定义:
为其他对象提供一种代理,以控制对这个象的访问.
-
使用场景:
无法或不想直接访问某个对象,或存在访问某个对象发生困难时,可以通过一个代理对象来简洁访问.为保证客户端使用的透明性,委托对象和代理对象要实现相同的接口.
-
静态代理
代理类以及被代理类实现有相同的实现,通过引用方式调用
被代理类写死在代码中,接口不同就需要重新定义不同的代理类
定义接口
public interface ILowSuit {
void submit();
void burden();
void defend();
void finish();
}
代理类
public class LowPerson implements ILowSuit {
ILowSuit in;
LowPerson(ILowSuit iLowSuit) {
this.in = iLowSuit;
}
@Override
public void submit() {
in.submit();
}
@Override
public void burden() {
in.burden();
}
@Override
public void defend() {
in.defend();
}
@Override
public void finish() {
in.finish();
}
}
被代理类
public class PersonA implements ILowSuit {
private final static String TAG = PersonA.class.getSimpleName();
@Override
public void submit() {
System.out.println(TAG + "提交申诉");
}
@Override
public void burden() {
System.out.println(TAG + "提交材料");
}
@Override
public void defend() {
System.out.println(TAG + "辩护开始");
}
@Override
public void finish() {
System.out.println(TAG + "期待胜利");
}
}
调用模块
public class StaticClient {
public static void main(String[] args) {
PersonA personA = new PersonA();
LowPerson lowPerson = new LowPerson(personA);
lowPerson.submit();
lowPerson.burden();
lowPerson.defend();
lowPerson.finish();
}
}
- 动态代理
通过实现Invocation接口来实现,复写invoke()方法,需要获取被代理类的ClassLoader,调用newProxyInstance(classLoader, new Class[]{ILowSuit.class}, dynamicProxy)
编码阶段不知道具体哪个类需要被代理,比较灵活可以实现一对多代理
动态代理代码
public class DynamicProxy implements InvocationHandler {
ILowSuit iLowSuit;
public DynamicProxy(ILowSuit iLowSuit) {
this.iLowSuit = iLowSuit;
}
//代理对象引用操作
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Objects result = (Objects) method.invoke(iLowSuit, args);
return result;
}
}
方法调用
public class DynamicClient {
public static void main(String[] args) {
PersonA personA = new PersonA();
DynamicProxy dynamicProxy = new DynamicProxy(personA);
ClassLoader classLoader = PersonA.class.getClassLoader();
ILowSuit iLowSuit = (ILowSuit) Proxy.newProxyInstance(classLoader, new Class[]{ILowSuit.class}, dynamicProxy);
iLowSuit.submit();
iLowSuit.burden();
iLowSuit.defend();
iLowSuit.finish();
}
}
代理类型
- 远程代理
为某个对象在不同的内存地址空间提供局部代理.使系统可以将Server部分的实现隐藏,以便Client可以不必考虑Server的存在
- 虚拟代理
使用一个代理对象表示一个十分耗资源的对象并在真正需要时才创建
- 保护代理
使用代理控制对原始对象的访问.该类型的代码常被用于原始对象有不同访问权限的情况
- 智能引用
在访问原始对象时执行一些自己的附加操作并对指向原始对象的引用计数