Java Proxy代理类的理解

Java Proxy代理类的理解

关键字: java proxy

    在Java中利用代理(Proxy)可以在运行时创建一个实现了一组给定接口的新类。

 

     在系统程序设计中,有时需要面对无法确定接口,却需要构造对象的情况。以前为了解决此问题,有些程序根据动态确定的接口,生成Java类文件,然后调用类加载器构造该对象,然后使用,这样一来无可避免性能问题。通过代理类,能够在不额外创建Java文件的情况下构造对象及调用该对象方法。

 

    使用代理的理由有很多,其中就有如下的情况:

    1.路由对远程服务器的方法调用

    2.在程序运行期间,将用户接口事件与行动关联起来

    3.调试时跟踪方法调用

 

     以下举出一例,使用代理和调用处理器跟踪方法调用

 

 

Java代码 复制代码
  1. import java.lang.reflect.InvocationHandler;   
  2. import java.lang.reflect.Method;   
  3. import java.lang.reflect.Proxy;   
  4. import java.util.Arrays;   
  5. import java.util.Random;   
  6.   
  7. public class ProxyTest   
  8. {     
  9.    public static void main(String[] args)   
  10.    {     
  11.       Object[] elements = new Object[1000];   
  12.   
  13.       // fill elements with proxies for the integers 1 ... 1000   
  14.       for (int i = 0; i < elements.length; i++)   
  15.       {   
  16.          Integer value = i + 1;   
  17.          Class[] interfaces = value.getClass().getInterfaces();   
  18.          InvocationHandler handler = new TraceHandler(value);   
  19.          Object proxy = Proxy.newProxyInstance(null,   
  20.             interfaces, handler);   
  21.          elements[i] = proxy;   
  22.       }   
  23.   
  24.       // construct a random integer   
  25.       Integer key = new Random().nextInt(elements.length) + 1;   
  26.   
  27.       // search for the key   
  28.       int result = Arrays.binarySearch(elements, key);   
  29.   
  30.       // print match if found   
  31.       if (result >= 0) System.out.println(elements[result]);   
  32.    }   
  33. }   
  34.   
  35. /**  
  36.    An invocation handler that prints out the method name  
  37.    and parameters, then invokes the original method  
  38. */  
  39. class TraceHandler implements InvocationHandler   
  40. {    
  41.    /**  
  42.       Constructs a TraceHandler  
  43.       @param t the implicit parameter of the method call  
  44.    */  
  45.    public TraceHandler(Object t)   
  46.    {     
  47.       target = t;   
  48.    }   
  49.   
  50.    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable//此方法在代理类中   
  51.    {                                                           //的方法被调用时均会被调用   
  52.       // print implicit argument   
  53.       System.out.print(target);   
  54.       // print method name   
  55.       System.out.print("." + m.getName() + "(");   
  56.       // print explicit arguments   
  57.       if (args != null)   
  58.       {   
  59.          for (int i = 0; i < args.length; i++)   
  60.          {     
  61.             System.out.print(args[i]);   
  62.             if (i < args.length - 1)   
  63.                System.out.print(", ");   
  64.          }   
  65.       }   
  66.       System.out.println(")");   
  67.   
  68.       // invoke actual method   
  69. //      return new Integer("123");   
  70.       return m.invoke(target, args);   
  71.    }   
  72.   
  73.    private Object target;   
  74. }  
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;

public class ProxyTest
{  
   public static void main(String[] args)
   {  
      Object[] elements = new Object[1000];

      // fill elements with proxies for the integers 1 ... 1000
      for (int i = 0; i < elements.length; i++)
      {
         Integer value = i + 1;
         Class[] interfaces = value.getClass().getInterfaces();
         InvocationHandler handler = new TraceHandler(value);
         Object proxy = Proxy.newProxyInstance(null,
            interfaces, handler);
         elements[i] = proxy;
      }

      // construct a random integer
      Integer key = new Random().nextInt(elements.length) + 1;

      // search for the key
      int result = Arrays.binarySearch(elements, key);

      // print match if found
      if (result >= 0) System.out.println(elements[result]);
   }
}

/**
   An invocation handler that prints out the method name
   and parameters, then invokes the original method
*/
class TraceHandler implements InvocationHandler
{ 
   /**
      Constructs a TraceHandler
      @param t the implicit parameter of the method call
   */
   public TraceHandler(Object t)
   {  
      target = t;
   }

   public Object invoke(Object proxy, Method m, Object[] args) throws Throwable//此方法在代理类中
   {  														   //的方法被调用时均会被调用
      // print implicit argument
      System.out.print(target);
      // print method name
      System.out.print("." + m.getName() + "(");
      // print explicit arguments
      if (args != null)
      {
         for (int i = 0; i < args.length; i++)
         {  
            System.out.print(args[i]);
            if (i < args.length - 1)
               System.out.print(", ");
         }
      }
      System.out.println(")");

      // invoke actual method
//      return new Integer("123");
      return m.invoke(target, args);
   }

   private Object target;
}

  在此处,代理类取代了可能需要额外创建的Java文件。

 

   当调用代理类的方法时,调用实现InvocationHandler接口的方法invoke,此时可以针对传入参数Method的不同,定义不同的方法体(操作)

 

   Proxy类的特性:

   1.代理(Proxy)类只有一个实例变量,即调用处理器(InvocationHandler)

   2.代理类需要的额外数据都必须存储在调用处理器中

   3.代理类一定是public和final.

   4.如果代理类实现的所有接口都是public,则代理类就不属于某个特定的包;否则所有的非公有接口都必须属于同一个包,代理类也属于这个包(此设定的目的是确定代理类的所属包)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值