美文网首页
Java核心技术 卷I - 代理(第11版)

Java核心技术 卷I - 代理(第11版)

作者: 程序员小白成长记 | 来源:发表于2020-06-21 01:07 被阅读0次

P273
利用代理可以在运行时创建实现了一组给定接口的新类。只有在编译时期无法确定需要实现哪个接口时才有必要使用代理。
代理类可以在运行时创建全新的类,这样的代理类能够实现你指定的接口

应用场景

  1. 将方法路由到远程服务器
  2. 在运行的程序中将用户界面事件与动作关联起来
  3. 为了调试,跟踪方法调动
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];

        for (int i = 0; i < elements.length; i++) {
            Integer value = i + 1;
            // 类处理器;实现InvocationHandler接口,参数为被引用对象
            InvocationHandler handler = new TraceHandler(value);
            // Proxy.newProxyInstance一个三个参数
            // 1, 类加载器
            // 2, 要实现的接口数组
            // 3, 调用处理器
            Object proxy = Proxy.newProxyInstance(
                    ClassLoader.getSystemClassLoader()
                    , 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]);
        }
    }
}

// 调用处理器:实现InvocationHandler(只有一个invoke方法)
class TraceHandler implements InvocationHandler {

    // 被调用对象的引用
    private Object target;

    // 通过构造函数将被调用对象传入
    public TraceHandler(Object t) {
        target = t;
    }

    // proxy:代理对象; method:代理方法; args:代理参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        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(")");
        }
        // 调用被调用方法真正执行,method:方法; targe:对象; args:参数
        return method.invoke(target, args);
    }
}

关于IDEA执行JDK动态代理debug时重复输出问题

相关文章

网友评论

      本文标题:Java核心技术 卷I - 代理(第11版)

      本文链接:https://www.haomeiwen.com/subject/ztinxktx.html