Java Proxy代理类的理解 - 小张三 - ITeye技术网站(转载)

关键字: java proxy

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

 

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

 

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

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

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

    3.调试时跟踪方法调用

 

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

 

 

Java代码 复制代码  收藏代码
  1. import java.lang.reflect.InvocationHandler;   
  2. import java.lang.reflect.Method;   

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值