代理模式
-------------------------------代理模式-------------------------------
使用条件: 在一个类的某些方法上 增加一些 额外操作.
优点: 1.不用修改 原来类的源代码,只需要在加一个类作为中间层增加新的操作.
2.解耦
静态代理:
-由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了
思路:
一个代理类,(原来类)
一个委托类,(中间层)
他们继承同一个接口.
接口中写有需要增加新操作的方法.
通过 调用委托类,用来调用代理类,在委托类调用代理类的方法中增加新操作
就完成了静态代理
缺点:
(1)由于委托类和代理类使用同一个接口,接口一旦改动,所有是实现类都需要更改.
(增加代码维护复杂度)
(2)代理对象只服务于一种对象,下面代码只为 Interface 提供了一种代理类,如果还有其他类型的对象,那么就要提供更多的代理类.
比如: 如果要为 OtherInterface 提供代理,我们还要创建一种代理 OtherInterface 的代理类
即静态代理类只能为特定的接口(Service)服务。如想要为多个接口服务则需要建立很多个代理
类。
(不适合规模较大的程序)
import java.lang.reflect.Method; interface Interface{ void doSomething(); void somethingElse(String arg); } class RealObject implements Interface{ public void doSomething() { System.out.println("Do something"); } public void somethingElse(String arg) { System.out.println("something " + arg); } } class SimpleProxy implements Interface{ private Interface proxied; public SimpleProxy(Interface proxied) { this.proxied = proxied; } public void doSomething() { System.out.println("SimpleProxy dosomething"); proxied.doSomething(); } public void somethingElse(String arg) { System.out.println("SimpleProxy " + arg); proxied.somethingElse(arg); } } public class Test{ public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse("args"); } public static void main(String[] args) throws ClassNotFoundException { consumer(new RealObject()); consumer(new SimpleProxy(new RealObject())); } }
---输出:
Do something
something args
SimpleProxy dosomething
Do something
SimpleProxy args
something args
为了解决静态代理的缺点,我们需要一个代理类完成全部的代理功能.
那么就出现了动态代理:
动态代理
-在程序运行时运用反射机制动态创建而成
import java.awt.image.RescaleOp; import java.lang.reflect.*; import java.util.regex.Matcher; import java.util.regex.Pattern; interface Interface{ void doSomething(); void somethingElse(String arg); } class RealObject implements Interface{ public void doSomething() { System.out.println("Do something"); } public void somethingElse(String arg) { System.out.println("something " + arg); } } class SimpleProxy implements InvocationHandler{ private Object proxied; /* 需要 java.lang.reflect.Proxy 类 * public static Object newProxyInstance( * ClassLoader loader, * Class<?>[] interfaces, * InvocationHandler h) * throws IllegalArgumentException * * CLassLoader loader:类的加载器 * Class<?> interfaces:得到全部的接口 * InvocationHandler h:得到InvocationHandler接口的子类的实例 */ public Object newProxyInstance(Object targetObject) { proxied = targetObject; return Proxy.newProxyInstance( targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } //Object proxy:被代理的对象 //Method method:要调用的方法 //Object[] args:方法调用时所需要参数 //需要 java.lang.reflect.InvocationHandler接口,然后重写 invoke方法 @Override public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{ Object res = method.invoke(proxied,args); Matcher mat = Pattern.compile("(?<=\\.)doSomething(?=\\()").matcher(method.toString()); if(mat.find()) { System.out.println("Test1"); } else { System.out.println("Test2 " + args[0]); } return res; } } public class Test{ public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse("args"); } public static void main(String[] args) throws ClassNotFoundException { consumer(new RealObject()); SimpleProxy simpleProxy = new SimpleProxy(); Interface interface1 = (Interface)simpleProxy.newProxyInstance(new RealObject()); consumer(interface1); } }
---输出:
Do something
something args
Do something
Test1
something args
Test2 args
参考资料:
- http://www.cnblogs.com/V1haoge/p/5860749.html
- http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
- http://www.runoob.com/design-pattern/proxy-pattern.html
- https://blog.csdn.net/pangqiandou/article/details/52964066
- https://www.cnblogs.com/baizhanshi/p/6611164.html (强烈推荐!!!)