动态代理调用invoke源码分析

动态代理的invoke方法是怎么实现实际委托对象方法的调用呢?
下面我们通过源码一步一步解析揭开它什么的面纱:
动态代理使用了Proxy.newProxyInstance方法动态创建代理类,我们看下newProxyInstance源码:

/**
@params loader 用于从动态生成的class字节流中加载创建代理类
@params interfaces 委托对象实现的接口列表
@params h 代理类方法调用处理器
@return 返回动态创建的代理类
*/
public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
 throws IllegalArgumentException
{
    //动态代理类方法调用处理程序即这里的h不能为空
    Objects.requireNonNull(h);
    //委托对象的接口列表
    final Class<?>[] intfs = interfaces.clone();
    //android中移除了安全相关的校验
    // Android-removed: SecurityManager calls
    /*
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }
    */

    /*
     * Look up or generate the designated proxy class.
     */
    //动态生成class文件字节流,然后通过loader加载此字节流创建代理类class
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        // Android-removed: SecurityManager / permission checks.
        /*
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }
        */
        //获取代理类的类构造对象
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        //如果class对象不可访问,则修改为可访问
        if (!Modifier.isPublic(cl.getModifiers())) {
            // BEGIN Android-changed: Excluded AccessController.doPrivileged call.
            /*
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
            */

            cons.setAccessible(true);
            // END Android-removed: Excluded AccessController.doPrivileged call.
        }
        // 通过类构造器创建代理实现类并返回
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}

newProxyInstance动态创建代理类的步骤是:

  • 校验代理类方法调用处理程序h不能为空
  • 动态生成代理类class文件格式字节流
  • 通过loader加载创建代表代理类的class对象
  • 根据代理类的构造器创建代理类
  • 返回动态创建生成的代理类
    怎么生成代理类class文件格式字节流的呢?
    我们先看下getProxyClass0方法:
private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
  if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    // If the proxy class defined by the given loader implementing
    // the given interfaces exists, this will simply return the cached copy;
    // otherwise, it will create the proxy class via the ProxyClassFactory
    return proxyClassCache.get(loader, interfaces);
}

通过上面的代码告诉我们委托对象能实现的接口数量不能超过65535,就是Short类型的最大值
我们再看proxyCache.get的实现,其中proxyCache是WeakCache的实现对象:

//WeakCache.java
/**
@params key 此处是类加载器loader
@params parameter 此处是代理类接口列表
*/
public V get(K key, P parameter) {
 //此处要求代理类接口不能为空
    Objects.requireNonNull(parameter);
  
    expungeStaleEntries();
    //生成CacheKey对象
    Object cacheKey = CacheKey.valueOf(key, refQueue);

    // lazily install the 2nd level valuesMap for the particular cacheKey
    //根据cachekey获取键值对valuesMap, valuesMap的key是接口列表的包装类,value是动态生成代理类的包装类
    ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
    if (valuesMap == null) {
        ConcurrentMap<Object, Supplier<V>> oldValuesMap
            = map.putIfAbsent(cacheKey,
                              valuesMap = new ConcurrentHashMap<>());
        if (oldValuesMap != null) {
            valuesMap = oldValuesMap;
        }
    }

    // create subKey and retrieve the possible Supplier<V> stored by that
    // subKey from valuesMap
    //根据代理类接口生成的key
    Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
    //动态生成代理类的包装类
    Supplier<V> supplier = valuesMap.get(subKey);
    //生成动态代理类的工厂类
    Factory factory = null;

    while (true) {
        //如果动态代理类包装类supplier不为空,则使用supplier 中的工厂类factory加载动态生成的class文件格式的代理类的字节流
        if (supplier != null) {
            // supplier might be a Factory or a CacheValue<V> instance
            //此处是factory加载动态生成的class文件格式的代理类的字节流的实现
            V value = supplier.get();
            if (value != null) {
                //此处返回动态生成的代理类
                return value;
            }
        }
        // else no supplier in cache
        // or a supplier that returned null (could be a cleared CacheValue
        // or a Factory that wasn't successful in installing the CacheValue)

        // lazily construct a Factory
        //如果动态生成代理类的工厂类为空,则创建新的工厂类
        if (factory == null) {
            factory = new Factory(key, parameter, subKey, valuesMap);
        }
       
        if (supplier == null) {
           //工厂类的包装类为空,则创建新的包装类supplier 
            supplier = valuesMap.putIfAbsent(subKey, factory);
            if (supplier == null) {
                // successfully installed Factory
                supplier = factory;
            }
            // else retry with winning supplier
        } else {
           //工厂类的包装类不为空,则替换包装类中的工作累
            if (valuesMap.replace(subKey, supplier, factory)) {
                // successfully replaced
                // cleared CacheEntry / unsuccessful Factory
                // with our Factory
                supplier = factory;
            } else {
                // retry with current supplier
                supplier = valuesMap.get(subKey);
            }
        }
    }
}

由上面的代码,大概知道通过map来存储动态生成的代理类,其中key是接口的包装类,value是动态代理类的包装类。

  • key的生成是通过subKeyFactory,subKeyFactory是KeyFactory的实现类,其实现很简单,只是对代理类接口进行包装:
private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], Object>{
    @Override
    public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
        switch (interfaces.length) {
            case 1: return new Key1(interfaces[0]); // the most frequent
            case 2: return new Key2(interfaces[0], interfaces[1]);
            case 0: return key0;
            default: return new KeyX(interfaces);
        }
    }
}

private static final class Key1 extends WeakReference<Class<?>> {
   private final int hash;

    Key1(Class<?> intf) {
        super(intf);
        this.hash = intf.hashCode();
    }

    @Override
    public int hashCode() {
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        Class<?> intf;
        return this == obj ||
               obj != null &&
               obj.getClass() == Key1.class &&
               (intf = get()) != null &&
               intf == ((Key1) obj).get();
    }
}

其他key1、keyx不展开说明

  • value是生成动态代理类的包装类,此包装类是实现了Supplier接口的Factory类,通过Factory的get方法动态生成代理类:
@Override
public synchronized V get() { // serialize access
   // re-check
    //从map中获取已经生成的动态代理类的包装类
    Supplier<V> supplier = valuesMap.get(subKey);
    if (supplier != this) {
        // something changed while we were waiting:
        // might be that we were replaced by a CacheValue
        // or were removed because of failure ->
        // return null to signal WeakCache.get() to retry
        // the loop
        return null;
    }
    // else still us (supplier == this)

    // create new value
    V value = null;
    try {
        //通过valueFactory的apply方法生成动态代理类
        value = Objects.requireNonNull(valueFactory.apply(key, parameter));
    } finally {
        if (value == null) { // remove us on failure
            valuesMap.remove(subKey, this);
        }
    }
    // the only path to reach here is with non-null value
    assert value != null;

    // wrap value with CacheValue (WeakReference)
    CacheValue<V> cacheValue = new CacheValue<>(value);

    // try replacing us with CacheValue (this should always succeed)
    if (valuesMap.replace(subKey, this, cacheValue)) {
        // put also in reverseMap
        reverseMap.put(cacheValue, Boolean.TRUE);
    } else {
        throw new AssertionError("Should not reach here");
    }

    // successfully replaced us with new CacheValue -> return the value
    // wrapped by it
    return value;
}

这里核心的实现是valueFactory的apply方法,valueFactory是ProxyClassFactory的实现类,我们来看下ProxyClassFactory的apply方法,看其是怎么实现生成动态代理类的:

public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

      Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
      //获取代理类接口的class对象,并校验是否是接口,如果不是则抛出错误
      for (Class<?> intf : interfaces) {
          /*
           * Verify that the class loader resolves the name of this
           * interface to the same Class object.
           */
          Class<?> interfaceClass = null;
          try {
              interfaceClass = Class.forName(intf.getName(), false, loader);
          } catch (ClassNotFoundException e) {
          }
          if (interfaceClass != intf) {
              throw new IllegalArgumentException(
                  intf + " is not visible from class loader");
          }
          /*
           * Verify that the Class object actually represents an
           * interface.
           */
          if (!interfaceClass.isInterface()) {
              throw new IllegalArgumentException(
                  interfaceClass.getName() + " is not an interface");
          }
          /*
           * Verify that this interface is not a duplicate.
           */
          if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
              throw new IllegalArgumentException(
                  "repeated interface: " + interfaceClass.getName());
          }
      }
      //动态代理类的包名
      String proxyPkg = null;     // package to define proxy class in
      //动态代理类的访问权限
      int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

      /*
       * Record the package of a non-public proxy interface so that the
       * proxy class will be defined in the same package.  Verify that
       * all non-public proxy interfaces are in the same package.
       */
      for (Class<?> intf : interfaces) {
          //根据代理类接口生成包名和访问权限
          int flags = intf.getModifiers();
          if (!Modifier.isPublic(flags)) {
              accessFlags = Modifier.FINAL;
              String name = intf.getName();
              int n = name.lastIndexOf('.');
              String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
              if (proxyPkg == null) {
                  proxyPkg = pkg;
              } else if (!pkg.equals(proxyPkg)) {
                  throw new IllegalArgumentException(
                      "non-public interfaces from different packages");
              }
          }
      }

      if (proxyPkg == null) {
          // if no non-public proxy interfaces, use the default package.
          proxyPkg = "";
      }

      {
          // Android-changed: Generate the proxy directly instead of calling
          // through to ProxyGenerator.
          //获取代理类接口的方法列表,并进行排序和返回类型校验
          List<Method> methods = getMethods(interfaces);
          Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
          validateReturnTypes(methods);
          //获取方法类别的异常列表
          List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
          //方法列表转为方法数组
          Method[] methodsArray = methods.toArray(new Method[methods.size()]);
         //异常列表转为异常数组
          Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);

          /*
           * Choose a name for the proxy class to generate.
           */
          //生成代理类唯一名称
          long num = nextUniqueNumber.getAndIncrement();
          String proxyName = proxyPkg + proxyClassNamePrefix + num;
          //根据类名、接口、类加载器、方法列表、异常列表,按照class文件格式先生成字节流,再生成动态代理类
          return generateProxy(proxyName, interfaces, loader, methodsArray,
                               exceptionsArray);
      }
  }

//native方法,其实现原理是根据类名、接口、类加载器、方法列表、异常列表,按照class文件格式先生成字节流,再生成动态代理类
@FastNative
private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
                                                 ClassLoader loader, Method[] methods,
                                                 Class<?>[][] exceptions);

按照这样的流程,我们可以总结动态代理的原理如下:
1、根据代理类接口先得到代理类的类全限名、方法列表、异常列表
2、根据步骤1中的类全限名、方法列表、异常列表、接口列表生成class文件格式的字节流,其中方法的实现会最终调用InvoationHanlder的invoke方法
3、使用类加载器加载步骤2中的字节流,创建生成动态代理类对象
4、使用步骤3中创建生成的代理类对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值