zoukankan      html  css  js  c++  java
  • 举例理解JDK动态代理

    JDK动态代理

    说到java自带的动态代理api,肯定离不开反射。JDK的Proxy类实现动态代理最核心的方法:

    public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
    

    这个方法的作用:在运行时,动态创建一组指定接口的实现类对象。其中的三大参数:

    • ClassLoader loader

      • 类加载器,主要作用是用来加载类的,把.class文件加载到jvm的方法区中,形成class对象
    • Class<?>[] interfaces

      • 实现的接口列表
    • InvocationHandler h

      • InvocationHandler 是一个接口,里面有且只有一个方法invoke(Object proxy, Method method, Object[] args),后面会介绍。

    我们可以先看个简单的例子:

    public class DynamicProxyDemo {
    
        @Test
        public void test1() {
    
            ClassLoader loader = this.getClass().getClassLoader();
            Class[] classes = {Human.class, Car.class};
            InvocationHandler h = new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("来了,老弟~");
                    return null;
                }
            };
    
            Human human = (Human) Proxy.newProxyInstance(loader, classes, h);
            human.male();
            human.toString();
            human.getClass();
        }
    
    }
    
    interface Human {
        Object male();
    }
    
    interface Car {
        Object bmw();
    }
    

    ​ 输出:

    来了,老弟~
    来了,老弟~
    

    可以看到,代码并没有报错,因为Proxy.newProxyInstance(loader, classes, h)返回的对象是实现了指定接口的类对象,所以强转成Human没有问题,当调用Human对象的方法时,会执行InvocationHandler里的invoke方法的语句。但是我当我调用getClass()方法时,并没有执行对应的语句,这是由于此方法是native方法,是调用本地的方法。

    既然调用代理对象的所有方法(个别除外)都会调用某个方法(invoke()),我们可以在里面进行任意操作,达到前置或者后置增强的效果。

    以下这图可以解析invoke(Object proxy, Method method, Object[] args)方法里的参数和human接口带参数的方法之间的关系:

    输出:

    来了,老弟~
    科比
    

    此方法也包含三大参数:

    • Object proxy
      • 当前对象,即生成的代理对象
    • Method method
      • 当前被调用的方法,即目标方法
    • Object[] args
      • 方法传入的参数

    未完待续。

  • 相关阅读:
    wxpython快速入门
    python核心编程 第四章 和第五章
    python核心编程 第三章
    python核心编程 第二章 快速入门
    Nginx 使用札记
    PHP 函数总结
    node.js安装部署
    linux
    在Linux上安装Git
    php超级全局变量
  • 原文地址:https://www.cnblogs.com/kobelieve/p/10441011.html
Copyright © 2011-2022 走看看