Java动态代理
在学习《Java编程思想》的时候看到了动态代理,觉得很有意思,现在来做一下总结。
代理模式的定义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
优点:
模式结构:
一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。
UML示意图
我们来看一个普通代理实现的例子:
1 //客户端接口 2 interface Interface { 3 4 void doSomething(); 5 6 void somethingElse(String arg); 7 } 8 9 //客户端实现类,就是执行业务逻辑的类 10 class RealObject implements Interface { 11 12 @Override 13 public void doSomething() { 14 // TODO Auto-generated method stub 15 System.out.println("doSomething"); 16 } 17 18 @Override 19 public void somethingElse(String arg) { 20 // TODO Auto-generated method stub 21 System.out.println("somethingElse" + arg); 22 } 23 24 } 25 26 //代理类 27 class SimpleProxy implements Interface { 28 29 private Interface proxied; 30 31 public SimpleProxy(Interface proxied) { 32 // TODO Auto-generated constructor stub 33 this.proxied = proxied; 34 } 35 36 @Override 37 public void doSomething() { 38 // TODO Auto-generated method stub 39 System.out.println("SimpleProxy doSomething"); 40 proxied.doSomething(); 41 } 42 43 @Override 44 public void somethingElse(String arg) { 45 // TODO Auto-generated method stub 46 System.out.println("SimpleProxy somethingElse "+arg); 47 proxied.somethingElse(arg); 48 } 49 50 } 51 52 public class SimpleProxyDemo{ 53 54 public static void consumer(Interface iface){ 55 iface.doSomething(); 56 iface.somethingElse("hello world"); 57 } 58 59 public static void main(String[] args){ 60 consumer(new RealObject()); 61 System.out.println("/*****************************/"); 62 consumer(new SimpleProxy(new RealObject())); 63 } 64 }
运行结果如下:
1 doSomething 2 somethingElsehello world 3 /*****************************/ 4 SimpleProxy doSomething 5 doSomething 6 SimpleProxy somethingElse hello world 7 somethingElsehello world
Java动态代理
Java的动态代理比代理的思想更向前迈进了一步,因为它可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作揭示调用的类型并确定相应的对策。
接下来我们来看一下Java动态代理的例子:
1 interface Interface { 2 3 void doSomething(); 4 5 void somethingElse(String arg); 6 } 7 8 class RealObject implements Interface { 9 10 @Override 11 public void doSomething() { 12 // TODO Auto-generated method stub 13 System.out.println("doSomething"); 14 } 15 16 @Override 17 public void somethingElse(String arg) { 18 // TODO Auto-generated method stub 19 System.out.println("somethingElse" + arg); 20 } 21 22 } 23 24 //动态代理类 25 class DynamicProxyHandler implements InvocationHandler{ 26 27 private Object proxied; 28 29 public DynamicProxyHandler(Object proxied) { 30 // TODO Auto-generated constructor stub 31 this.proxied = proxied; 32 } 33 34 @Override 35 public Object invoke(Object proxy, Method method, Object[] args) 36 throws Throwable { 37 // TODO Auto-generated method stub 38 System.out.println("****proxy: " + proxy.getClass()+ 39 ", method: "+method+ ", args: "+ args); 40 41 if(args != null){ 42 for (Object arg : args) { 43 System.out.println(" "+ arg); 44 } 45 } 46 47 return method.invoke(proxied, args); 48 } 49 } 50 51 class SimpleDynamicProxy{ 52 53 public static void consumer(Interface iface){ 54 iface.doSomething(); 55 iface.somethingElse("hello world"); 56 } 57 58 public static void main(String[] args){ 59 RealObject real = new RealObject(); 60 consumer(real); 61 62 System.out.println("/*******************************/"); 63 64 Interface proxy = (Interface)Proxy.newProxyInstance( 65 Interface.class.getClassLoader(), 66 new Class[]{Interface.class}, 67 new DynamicProxyHandler(real)); 68 69 consumer(proxy); 70 71 } 72 73 }
运行结果如下:
1 doSomething 2 somethingElsehello world 3 /*******************************/ 4 ****proxy: class com.sun.proxy.$Proxy0, method: public abstract void Interface.doSomething(), args: null 5 doSomething 6 ****proxy: class com.sun.proxy.$Proxy0, method: public abstract void Interface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@756095fc 7 hello world 8 somethingElsehello world
通过调用静态方法Proxy.newProxyInstance()可以创建动态代理。这个方法需要得到一个类加载器(你通常可以从已经被加载的对象中获取其类加载器,然后传递给它),一个你希望该代理实现的接口列表(不是类或者抽象类),以及InvocationHandler接口的一个实现。动态代理可以将所有调用重定向到调用处理器,因此通常会向调用处理器的构造器传递一个“实际”对象的引用,从而使得调用处理器执行其中介任务时,可以将请求转发。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。