代理设计模式 概述
为目标对象提供一个代理对象,然后让代理对象控制对目标对象的引用。
静态代理:代理类在编译时就已实现好,Java编译完成后代理类就是一个.class文件
动态代理:代理类在运行时生成,在运行时动态生成class文件并加载到jvm中
使用场景
生活中很多场景都会用到代理模式,最直观的例子就是代购,比如你想要买一款最新的电子产品,但是国内没有,只能找代购到国外淘宝,那么“你”就是一个目标对象,代购者就是一个代理对象,让代购者帮你去买你所想要的东西即可。
静态代理 代码走一波
首先我有一个愿望,就是买一辆奥迪,或者想买很多稀奇古怪的东西创建一个接口声明你想让代购帮你买的东西
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public interface IWish { void buyAudi () ; void buyIMac () ; }
创建真实对象类,就是我
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Me implements IWish { @Override public void buyAudi () { System.out.println("刷卡付钱" ); System.out.println("试驾" ); System.out.println("..." ); } @Override public void buyIMac () { System.out.println("刷卡付钱" ); System.out.println("试用" ); System.out.println("..." ); } }
创建代理类(Proxy),即代购者,通过代理类的构造函数获取真实对象我,间接的执行方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class Saler implements IWish { private IWish me; public Saler (IWish me) { this .me = me; } @Override public void buyAudi () { System.out.println("办理一系列买车业务" ); me.buyAudi(); System.out.println("买车业务办理完毕" ); } @Override public void buyIMac () { System.out.println("办理一系列买Mac业务" ); me.buyIMac(); System.out.println("买Mac业务办理完毕" ); } }
最后调用
1 2 3 4 5 6 7 8 9 public class ProxyClient { public static void main (String[] args) { Me me = new Me(); IWish saler = new Saler(me); saler.buyAudi(); System.out.println("--------" ); saler.buyIMac(); } }
输出结果为:
办理一系列买车业务 刷卡付钱 试驾 …
买车业务办理完毕 /——– 办理一系列买Mac业务 刷卡付钱 试用 … 买Mac业务办理完毕
静态代理的优缺点 优点 :
缺点 :
会发现代码优点冗余
增加了一个代理对象,会造成请求速度变慢
动态代理 Java中提供了对动态代理的封装,代码中的注释还是比较清楚的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class DynamicProxyClient { public static void main (String[] args) { IWish me = new Me(); IWish proxy = (IWish) Proxy.newProxyInstance(IWish.class.getClassLoader(), new Class<?>[] { IWish.class }, new WishInvocationHandler(me)); proxy.buyAudi(); System.out.println("=================" ); proxy.buyIMac(); } public static class WishInvocationHandler implements InvocationHandler { private IWish me; public WishInvocationHandler (IWish me) { this .me = me; } @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代购前一些需要做的事情" ); method.invoke(me, args); System.out.println("代购完毕" ); return null ; } } }
动态代理的优缺点 优点 :
减少了代理类中的很多重复性代码,更注重操作过程
由于Java的单继承性,只能针对接口创建代理类,不能针对类创建代理类