• 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

  • 相关阅读:
    android下socket编程问题:服务器关闭时,客户端发送请求的异常处理
    MySQL新建用户,授权,删除用户,修改密码
    jquery验证表单代码
    Incorrect key file for table '/tmp/#sql_46fd_0.MYI'; try to repair it
    初试百度地图API
    Android控件之GridView探究
    使用Intent调用内置应用程序
    消除SDK更新时的“https://dl-ssl.google.com refused”错误
    A folder failed to be renamed or moved--安装Android SDK的问题
    windows下搭建svn服务器
  • 原文地址:https://www.cnblogs.com/qiaomu/p/4378255.html
Copyright © 2020-2023  润新知