一、简述
代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。
其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中的中介者对象也是代理模式的应用,其他的对象的交互都是交给了中介者对象处理的。而在生活中就更多类似代理模式的例子,例如:抢票插件、科学上网等等。
/**抽象主题*/public interface Subject {public void visit();}
/**被代理主题*/public class RealSubject implements Subject {@Overridepublic void visit() {System.out.print("this is real subject");}}
/**代理主题*/public class ProxySubject implements Subject {//真实主题private Subject realSubject;public ProxySubject(@NotNull Subject subject){realSubject = subject;}@Overridepublic void visit() {System.out.print("proxy start");realSubject.visit();System.out.print("proxy end");}}
/**客户类*/public class Client {public static void main(String[] args){//创建被代理对象RealSubject realSubject = new RealSubject();//创建代理对象ProxySubject proxySubject = new ProxySubject(realSubject);//调用方法proxySubject.visit();}}
输出结果:proxy startthis is real subjectproxy end
二、动态代理
上一部分中所讲述的,其实是静态代理,也就是在代码的编译阶段生成代理类来完成代理对象的一系列操作。而动态代理则是在运行时动态生成代理类对象。代理对象的生成是利用JDK中java.lang.reflect.Proxy类,使用newProxyInstance方法可以创建一个我们所需要的代理对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {//代码省略...}
newProxyInstance方法是Proxy的一个静态方法,并且接收三个参数
其中InvocationHandler的invoke方法如下:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;`
返回值则是代理对象调用方法时所返回的值
依然使用Subject作为例子,看看简单的代码实现(代码没有封装)
//创建被代理对象Subject realSubject = new RealSubject();//创建代理对象Subject subject = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Subject.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return method.invoke(realSubject, args);}});subject.visit();
从代码上来看,比之前的静态代理要简单很多,没有那么多的类和对象;但是相对的在代码性能上有所牺牲,而且对于不太熟悉反射相关的知识的开发者并不是太友好。
通过反射类Proxy和InvocationHandler回调接口实现的JDK动态代理,要求被代理类必须实现一个接口,但事实上并不是所有类都有接口,对于没有实现接口的类,便无法使用该方方式实现动态代理。
三、其他代理分类
静态代理和动态代理是代码方面来区分的代理模式,也可以从适用范围来区分不同类型的代理实现
这里要注意的是,静态和动态代理都可以应用于上述4种情形,两者是各自独立的变化。
四、总结
代理模式使用非常广泛,基本在其他的设计模式中也能看到代理模式的影子,但是使用时针对性较强,而且模式本身并没有什么突出的优缺点,基本上可以放心使用
