1、介绍
代理模式:为其他对象提供一种代理一控制对这个对象的访问。
在代理模式中,有四个角色
- Subject: 抽象主题类,声明主题类与代理的公共接口方法
- RealSubject: 主题类,代理类所代表的主题,通过代理类调用主题类
- Proxy: 代理类,持有对主题类的引用
- Client: 客户端
其中代理模式分为静态代理和动态代理,静态代理是在运行前就已经存在代理类的class文件,动态代理在代码运行时通过反射动态生成代理类对象。
2、实现(静态)
2.1、抽象主题类
抽象主题类含有主题类和代理类共同的接口和方法。
public interface Subject{
void play();
}
2.2、主题类
主题类实现抽象主题类的方法。
publice class RealSubject implement Subject{
@Override
public void play(){
...
}
}
2.3、代理类
代理类同样实现抽象主题类的方法,并且在代理类内部持有主题类。
public class Proxy implement Subject{
private Subject s;
public Proxy(Subject s){
this.s=s;
}
@Override
public void play(){
s.play();
}
}
2.4、客户端调用
Subject realSubject =new RealSubject();
Subject proxy =new Proxy(realSubject);
proxy.play();
3、实现(动态)
动态代理会由代码运行时动态决定代理谁,Java有动态代理接口InvocationHandler,实现这个接口并重写invoke方法。
3.1、创建动态代理类
public class DynamicProxy implements InvocationHandler{
private Object obj;
public DynamicProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
Object result=method.invoke(obj,args);
if(method.getName().equals("play")){
...
}
reutrn result;
}
}
在这个动态代理类中声明一个Object引用,引用指向代理类,调用代理类的方法在invoke中执行。
3.2、客户端调用
//首先创建主题类即RealSubject
Subject realSubject =new RealSubject();
//创建动态代理dynamicProxy
DynamicProxy dynamicProxy =new DynamicProxy(realSubject);
//创建RealSubject的ClassLoader
ClassLoader classLoader=realSubject.getClass().getClassLoader();
//动态创建代理类proxy
Subject proxy=(Subject)Proxy.newProxyInstance(classLoader,new Class[] {Subject.class},dynamicProxy);
//调用代理类中的方法
proxy.play();
在动态代理中通过newProxyInstance来得到动态代理类,之后在调用动态代理类的过程中会使用invoke方法。
4、其他
优点
- 主题类实现实际的业务逻辑,无需关注其他部分
- 主题类具有高拓展性,实现了公共接口,在主题类发生变化是代理类无需修改
缺点
- 增加了代理对象,因此会造成处理的速度变慢
- 增加了代码复杂度