动态代理模式

Java动态代理主要涉及到两个类:

  • Proxy类:Proxy类的设计用到代理模式的设计思想,Proxy类对象实现了代理目标的所有接口,并代替目标对象进行实际的操作。但这种替代不是一种简单的替代,这样没有任何意义,代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截。所以,Proxy应该包括一个方法拦截器,来指示拦截到方法调用时做何种处理。InvocationHandler就是拦截器的接口。
  • InvocationHandler接口:此接口仅定义了一个方法

    Object invoke(Object proxy , Method method , Object[] args) throws Throwable

   参数:

    Object proxy :被代理的对象;

    Method method:被代理的方法(要调用的方法);

    Object args[]:method调用时所需要的参数;

    返回值Object为代理实例的方法调用返回的值。

 

Proxy类定义了一个静态方法:

public static Object newProxyInstance(ClassLoader loader , Class<?>[] interfaces , InvocationHandler h) throws IllegalArgumentException

作用:生成动态代理类实例

参数:ClassLoader loader:代理类的类加载器

     Class<?>[] interfaces:代理类要实现的接口列表

     InvocationHandler h:得到InvocationHandler接口的子类实例

返回值:一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口

 

示例代码:

 1 import java.lang.reflect.InvocationHandler ;
 2 import java.lang.reflect.Proxy ;
 3 import java.lang.reflect.Method ;
 4 interface Subject{
 5     public String say(String name,int age) ;    // 定义抽象方法say
 6 }
 7 class RealSubject implements Subject{    // 实现接口
 8     public String say(String name,int age){
 9         return "姓名:" + name + ",年龄:" + age ;
10     }
11 };
12 class MyInvocationHandler implements InvocationHandler{
13     private Object obj ;
14     public Object bind(Object obj){
15         this.obj = obj ;    // 真实主题类
16         return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this) ;
17     }
18     public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
19         Object temp = method.invoke(this.obj,args) ;    // 调用方法
20         return temp ;
21     }
22 };
23 public class DynaProxyDemo{
24     public static void main(String args[]){
25         Subject sub = (Subject)new MyInvocationHandler().bind(new RealSubject()) ;
26         String info = sub.say("中华",30) ;
27         System.out.println(info) ;
28     }
29 };

可以把InvocationHandler接口的子类看成一个代理的最终操作类。

这里因为是动态代理,所以MyInvocationHandler 类中的属性成员obj被声明为Object类型,而不是具体的某个类,最终需要使用时用向下转型即可。

在DynaProxyDemo类中调用sub.say("中华",30)语句时,实际就是利用Proxy.newProxyInstance方法生成的代理实例来调用接口中的say方法,

因为有InvocationHandler的子类MyInvocationHandler的干预,所以会自动进入invoke方法的调用。

 

 

参考: http://blog.csdn.net/vipwalkingdog/article/details/7685873

posted @ 2014-04-02 20:05  sky钦  阅读(89)  评论(0)    收藏  举报