Java代理的小例子

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

需要一个调用处理器(invocation handler),调用处理器需实现InvocationHandler接口。无论何时调用代理对象的方法,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的调用参数。

创建代理对象,需要使用Proxy类的newProxyInstance方法。此方法有三个参数:

1、一个类加载器(class loader),null代表默认

2、接口数组

3、一个调用处理器

使用代理的作用:

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

2、在程序运行期间,将用户接口事件与动作关联起来(spring AOP就是)

3、为调试,跟踪方法调用

下面的例子就是跟踪方法调用。以二分查找法为例,注:Integer实现comparable接口,代理类覆盖toString方法:

 

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;

import javax.swing.JOptionPane;
import javax.swing.Timer;


public class TextMain {
public static void main(String args[]) {
    Object[] elements=new Object[1000];
    for(int i=0;i<elements.length;i++){
        Integer value=i+1;
        InvocationHandler handler=new TraceHandler(value);
        Object proxy=Proxy.newProxyInstance(null, new Class[]{Comparable.class}, handler);
        elements[i]=proxy;
        
    }
    Integer key=new Random().nextInt(elements.length)+1;
    int result=Arrays.binarySearch(elements, key);
    if(result>=0)System.out.println(elements[result]);
}


}
class TraceHandler implements InvocationHandler{

    private Object target;
    public TraceHandler(Object t){
        target=t;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        System.out.print(target);
        System.out.print("."+method.getName()+"(");
        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(")");
                
        return method.invoke(target, args);
        
    }
    
}

 运行结果:

500.compareTo(269)
250.compareTo(269)
375.compareTo(269)
312.compareTo(269)
281.compareTo(269)
265.compareTo(269)
273.compareTo(269)
269.compareTo(269)
269.toString()
269

  InvocationHandler 中的invoke方法,定义了代理对象调用方法时希望执行的动作(跟踪,记录日志)

  Proxy中newProxyInstance构造一个实现指定接口的代理类的实例,所有方法都将调用给定处理器对象的invoke方法。

  所有代理类都扩展于proxy类,Proxy只有一个实例域——调用处理器InvocationHandler

posted @ 2015-03-30 15:45  ~每天进步一点点~  阅读(844)  评论(0编辑  收藏  举报