wkynf

简介

java.lang.reflect.Proxy是整个jdk中实现动态代理的核心 类,本文主要介绍Proxy类的实现,关于Proxy类的使用请自行查阅其他资料。

Field

  • constructorParams:构造函数的参数,用于代理类的核心的逻辑实现,关于InvocationHandler这个接口的介绍不是本文的重点,此处不做介绍。

private static final Class<?>[] constructorParams =
  { InvocationHandler.class };
  • proxyClassCache: 代理类的缓存,此类是一个二级缓存的实现,利用WeakReference的特性,当内存占用过高的时候会JVM自动进行回收缓存中的数据。

private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
   proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
  • h: InvocationHandler接口,用于此代理实例的调用处理程序。

Inner Class

  • KeyFactory:顾名思义,缓存代理的key的工厂实现,此类仅一个方法,实现了BiFunction接口,具体代码如下

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);
      }
  }
}

由以上代码可见,该类的实现分为委托给了Key0,Key1,Key2,KeyX这四个类实现,其中key0是一个Object,其他的类Key1,Key2,KeyX则是分别用不同的实现对hashcode和equals方法进行了不同的实现,大同小异。这里则分别简单的做一下解释。

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();
  }
}
private static final class Key2 extends WeakReference<Class<?>> {
   private final int hash;
   private final WeakReference<Class<?>> ref2;

   Key2(Class<?> intf1, Class<?> intf2) {
       super(intf1);
       hash = 31 * intf1.hashCode() + intf2.hashCode();
       ref2 = new WeakReference<Class<?>>(intf2);
  }

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

   @Override
   public boolean equals(Object obj) {
       Class<?> intf1, intf2;
       return this == obj ||
              obj != null &&
              obj.getClass() == Key2.class &&
              (intf1 = get()) != null &&
              intf1 == ((Key2) obj).get() &&
              (intf2 = ref2.get()) != null &&
              intf2 == ((Key2) obj).ref2.get();
  }
}
private static final class KeyX {
   private final int hash;
   private final WeakReference<Class<?>>[] refs;

   @SuppressWarnings("unchecked")
   KeyX(Class<?>[] interfaces) {
       hash = Arrays.hashCode(interfaces);
       refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
       for (int i = 0; i < interfaces.length; i++) {
           refs[i] = new WeakReference<>(interfaces[i]);
      }
  }

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

   @Override
   public boolean equals(Object obj) {
       return this == obj ||
              obj != null &&
              obj.getClass() == KeyX.class &&
              equals(refs, ((KeyX) obj).refs);
  }

   private static boolean equals(WeakReference<Class<?>>[] refs1,
                                 WeakReference<Class<?>>[] refs2) {
       if (refs1.length != refs2.length) {
           return false;
      }
       for (int i = 0; i < refs1.length; i++) {
           Class<?> intf = refs1[i].get();
           if (intf == null || intf != refs2[i].get()) {
               return false;
          }
      }
       return true;
  }
}
  • ProxyClassFactory: 顾名思义, 代理类的生产工厂类,用于生成代理类,此类也是实现了BiFunction,技能一个apply方法,最终根据ClassLoader,Interface,proxyName参数调用java.lang.reflect.Proxy#defineClass0这个本地方法生成代理类。

private static final class ProxyClassFactory
   implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
   // 代理类名称的前缀,我们看到的代理类的名称都有这个前缀就是这个原因
   private static final String proxyClassNamePrefix = "$Proxy";

   // 用于生成代理类名称的唯一的序号
   private static final AtomicLong nextUniqueNumber = new AtomicLong();

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

       Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
       for (Class<?> intf : interfaces) {
           /*
            * 验证类加载器是否将此接口的名称解析为同一类对象
            */
           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");
          }
           /*
            * 验证此类实际是否是一个接口
            */
           if (!interfaceClass.isInterface()) {
               throw new IllegalArgumentException(
                   interfaceClass.getName() + " is not an interface");
          }
           /*
            * 校验接口是不重复的
            */
           if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
               throw new IllegalArgumentException(
                   "repeated interface: " + interfaceClass.getName());
          }
      }
// 代理类包名
       String proxyPkg = null;  
       //代理类的访问修饰符
       int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

       /*
        * 记录非public的代理接口的包,以至于代理类的定义是相同的包,验证所有的非public的代理接口在相同的包中。
        */
       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));
               

分类:

技术点:

相关文章:

  • 2018-09-03
  • 2021-03-09
  • 2018-10-19
  • 2021-02-04
  • 2018-02-24
  • 2019-11-08
猜你喜欢
  • 2021-10-19
  • 2021-11-17
  • 2021-03-31
  • 2021-09-04
  • 2021-06-20
  • 2020-01-09
  • 2018-01-08
  • 2019-12-27
相关资源
相似解决方案