Proxy动态代理源码分析

Proxy/InvocationHandler

Posted by Jay on July 9, 2019

Proxy动态代理源码分析

Proxy类主要用于实现动态代理机制,即代理类在程序运行时创建。下面先从一个实例出发,看看JDK如何实现动态代理。

一、实例

首先定义一个代理接口以及其实现类:

public interface Subject { // 代理接口
    void request();
}

public class RealSubject implements Subject { // 实现
    @Override
    public void request() {
        System.out.println("real");
    }
}

其次,定义方法调用的处理Handler:

public class ProxyHandler implements InvocationHandler {
    private Subject subject; // 持有被代理对象的引用

    public ProxyHandler(Subject subject) {
        this.subject = subject;
    }

  	// 方法调用, proxy为生成的代理类实例
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object res = method.invoke(subject, args);
        System.out.println("after");
        return res;
    }
}
// 调用处理器
public interface InvocationHandler {
		// 动态代理方法调用处理
  	// proxy:代理类实例,method调用方法,args调用参数
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

下面给出动态代理的效果:

public class DynamicProxyDemo {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject(); // 被代理实例
      	// 代理类实例
        Subject s = (Subject)  Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
                new Class[]{Subject.class}, new ProxyHandler(realSubject));
        s.request(); // 在代理类实例上调用request方法
        System.out.println(s.getClass().getName()); // 代理类的全限定类名
    }
}

// 输出:
before
real
after
com.sun.proxy.$Proxy0

根据测试结果可见,在被代理对象realSubject的request方法调用前后,执行了类似于AOP的代码。这是依赖于JDK的Proxy API实现的动态代理机制,在程序运行前并不存在代理类代码,而是在程序运行期间由Proxy API动态生成的。下面分析Proxy动态代理的实现机制。

二、Proxy类分析

1.重要属性
/** parameter types of a proxy class constructor */ // 代理类构造器参数的类型
private static final Class<?>[] constructorParams =
    { InvocationHandler.class };

// a cache of proxy classes // 代理类的缓存 WeakCache<ClassLoader, 代理接口数组, 代理类>
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
    proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

// the invocation handler for this proxy instance. 
// 代理类实例对应的调用处理器,在生成代理类实例的时候初始化
protected InvocationHandler h;
2.构造器
private Proxy() { // 私有构造器,禁止外部初始化
}

protected Proxy(InvocationHandler h) { // 从动态代理类(Proxy子类)构造一个Proxy实例,由子类调用
    Objects.requireNonNull(h);
    this.h = h;
}
3.创建/获取代理类getProxyClass
// loader: 类加载器,interfaces: 代理接口
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)
    throws IllegalArgumentException
{
    final Class<?>[] intfs = interfaces.clone(); // 代理接口数组浅拷贝
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs); // 检查创建代理类的权限
    }

    return getProxyClass0(loader, intfs); // 生成代理类或从缓存中获取
}

getProxyClass0实现:

// loader: 类加载器,interfaces: 代理接口
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
    if (interfaces.length > 65535) { // 代理接口数目不能超过65535
        throw new IllegalArgumentException("interface limit exceeded");
    }

  	// 由ClassLoader loader定义的并且实现了给定代理接口的代理类如果已存在,则直接返回缓存的代理类;
  	// 否则通过ProxyClassFactory生成代理类并缓存。
    return proxyClassCache.get(loader, interfaces);
}

如果根据给定的类加载器和代理接口数组,代理类已经缓存于proxyClassCache(WeakCache,代理类缓存),则直接返回缓存的结果;否则需要使用ProxyClassFactory生成代理类并缓存。

private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

下面先看WeakCache的结构,再分析其get(K key, P parameter)方法的实现。

(1) WeakCache类定义
// K: ClassLoader, P: Class<?>[], V: Proxy子类,代理类
final class WeakCache<K, P, V> { // 用于缓存生成的代理类
		// 引用队列,用于K(ClassLoader)被GC回收时,保存CacheKey。
    private final ReferenceQueue<K> refQueue = new ReferenceQueue<>();
    // the key type is Object for supporting null key
  	// 缓存代理类<CacheKey(ClassLoader), <Key1、Key2、KeyX等实例, CacheValue(代理类)>>
    private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
        = new ConcurrentHashMap<>();
  	// <CacheValue(代理类), TRUE>
    private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
        = new ConcurrentHashMap<>();
    private final BiFunction<K, P, ?> subKeyFactory; // Proxy.KeyFactory类实例,生成subKey
    private final BiFunction<K, P, V> valueFactory; // Proxy.ProxyClassFactory类实例,生成value

  	// 构造WeakCache实例
    // subKeyFactory:(key, parameter) -> sub-key,valueFactory:(key, parameter) -> value
    public WeakCache(BiFunction<K, P, ?> subKeyFactory, BiFunction<K, P, V> valueFactory) {
        this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
        this.valueFactory = Objects.requireNonNull(valueFactory);
    }
 		// ...下面代码省略   
}
(2) WeakCache.get方法

Proxy.getProxyClass0方法中调用了这个方法,用于获取缓存的代理类,或者生成代理类并缓存。

// K key: ClassLoader, P parameter: 代理接口数组 Class<?>[],返回代理类,即Proxy子类
public V get(K key, P parameter) {
    Objects.requireNonNull(parameter); // parameter不能为null

    expungeStaleEntries(); // 删除遗留的无效entry

    Object cacheKey = CacheKey.valueOf(key, refQueue); // 生成CacheKey,弱引用key

    // lazily install the 2nd level valuesMap for the particular cacheKey
    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) { // 本次putIfAbsent插入之前,其他线程已经插入了map
            valuesMap = oldValuesMap; // 使用已插入的map
        }
    }

    // create subKey and retrieve the possible Supplier<V> stored by that
    // subKey from valuesMap
  	// 创建subKey,并从valuesMap获取Supplier<V>
    Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
    Supplier<V> supplier = valuesMap.get(subKey);
    Factory factory = null; // 作用:创建代理类,并包装为CacheValue,缓存在valuesMap中

    while (true) {
	      // supplier可能是已缓存的CacheValue实例,或者是用于创建CacheValue的Factory
        if (supplier != null) { 
            // supplier might be a Factory or a CacheValue<V> instance
            V value = supplier.get(); // 获取value(获取代理类缓存或者创建代理类)
            if (value != null) { // 从CacheValue中获取代理类,或者Factory创建代理类成功,返回代理类
                return value;
            }
        }
      	// 到这里说明
      		1.缓存中无supplier. 或者
          2.由于CacheValue弱引用value即代理类Class当代理类被GC时此时CacheValue无效
            CacheValue.get()返回null. 或者
          3.Factory创建代理类失败(CacheValue)
        // 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实例
            factory = new Factory(key, parameter, subKey, valuesMap);
        }

        if (supplier == null) { // supplier为空,放入valuesMap
            supplier = valuesMap.putIfAbsent(subKey, factory);// null或已插入的supplier
            if (supplier == null) {
                // successfully installed Factory
                supplier = factory; // supplier成功插入valuesMap
            }
	          // 在当前线程将supplier插入valuesMap之前,已经有其他线程将supplier插入了valuesMap,
          	// 则使用已插入的supplier,重试
            // else retry with winning supplier 
        } else {
          	// supplier不为null,从上面代码supplier.get()看,是获取value失败了,
          	// 因此用新的factory替换原supplier
            if (valuesMap.replace(subKey, supplier, factory)) {
                // successfully replaced
                // cleared CacheEntry / unsuccessful Factory
                // with our Factory
                supplier = factory; // 替换无效的CacheValue或创建代理类失败的Factory为新factory
            } else {
                // retry with current supplier
                supplier = valuesMap.get(subKey); // 替换失败,则使用当前的supplier重试
            }
        }
    }
}
// 删除遗留的无效entry
private void expungeStaleEntries() {
    CacheKey<K> cacheKey;
 		// CacheKey弱引用Key(ClassLoader),当Key被GC回收时,CacheKey会被放入引用队列
    while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
        cacheKey.expungeFrom(map, reverseMap); // 清理两个map
    }
}

subKeyFactory.apply(key, parameter)实际调用的是Proxy.KeyFactory.apply方法:

// 根据ClassLoader,代理接口数组生成subKey
private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], Object>
{
    @Override
    public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
    		// 根据代理接口数量来生成subKey,即Key1、Key2、KeyX的实例或key0
        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);
        }
    }
}

Proxy中的Key1、Key2、KeyX、key0定义如下:

// 代理类如果没有实现接口,使用的key
private static final Object key0 = new Object();

// 代理类如果实现了1个接口,使用的key。Key1弱引用该接口
private static final class Key1 extends WeakReference<Class<?>> {
    private final int hash;

    Key1(Class<?> intf) {
        super(intf); // 弱引用
        this.hash = intf.hashCode(); // 接口hash
    }

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

// 代理类如果实现了2个接口,使用的key。Key2弱引用这两个接口
private static final class Key2 extends WeakReference<Class<?>> {
    private final int hash;
    private final WeakReference<Class<?>> ref2;

    Key2(Class<?> intf1, Class<?> intf2) {
        super(intf1); // 弱引用intf1
        hash = 31 * intf1.hashCode() + intf2.hashCode(); // 计算hash
        ref2 = new WeakReference<Class<?>>(intf2); // 弱引用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();
    }
}

// 代理类如果实现了3个及以上的接口,使用的key。KeyX弱引用这些接口
private static final class KeyX {
    private final int hash;
    private final WeakReference<Class<?>>[] refs; // 弱引用

    @SuppressWarnings("unchecked")
    KeyX(Class<?>[] interfaces) {
        hash = Arrays.hashCode(interfaces); // 计算hash
        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) { // 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;
    }
}
(3) WeakCache.CacheKey类

CacheKey实例作为private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map = new ConcurrentHashMap<>();的第一级Key。

// CacheKey弱引用key,即ClassLoader
private static final class CacheKey<K> extends WeakReference<K> {

    // a replacement for null keys
    private static final Object NULL_KEY = new Object();
		// 生成CacheKey
    static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {
        return key == null
               // null key means we can't weakly reference it,
               // so we use a NULL_KEY singleton as cache key
               ? NULL_KEY
               // non-null key requires wrapping with a WeakReference
               : new CacheKey<>(key, refQueue); // 弱引用
    }

    private final int hash;

    private CacheKey(K key, ReferenceQueue<K> refQueue) {
        super(key, refQueue); // 弱引用key
        this.hash = System.identityHashCode(key);  // compare by identity == 比较
    }

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

    @Override
    public boolean equals(Object obj) {
        K key;
        return obj == this ||
               obj != null &&
               obj.getClass() == this.getClass() &&
               // cleared CacheKey is only equal to itself 
          		 // 如果CacheKey已经无效(key被GC回收),则它只与自己相等。 == 比较
               (key = this.get()) != null &&
               // compare key by identity ==比较
               key == ((CacheKey<K>) obj).get();
    }

  	// private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map = new ConcurrentHashMap<>();
    // private final ConcurrentMap<Supplier<V>, Boolean> reverseMap = new ConcurrentHashMap<>();
    void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
                     ConcurrentMap<?, Boolean> reverseMap) {
        // removing just by key is always safe here because after a CacheKey
        // is cleared and enqueue-ed it is only equal to itself
        // (see equals method)... == 比较,总是可以安全的移除valuesMap
        ConcurrentMap<?, ?> valuesMap = map.remove(this); // 删除valuesMap
        // remove also from reverseMap if needed
        if (valuesMap != null) {
            for (Object cacheValue : valuesMap.values()) {
                reverseMap.remove(cacheValue); // 清除reverseMap缓存
            }
        }
    }
}
(4) WeakCache.CacheValue类

CacheValue实例作为private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map = new ConcurrentHashMap<>();第二级key的value。

private interface Value<V> extends Supplier<V> {}

// 弱引用value,即代理类Class
private static final class CacheValue<V> extends WeakReference<V> implements Value<V>
{
    private final int hash;

    CacheValue(V value) {
        super(value); // 弱引用
        this.hash = System.identityHashCode(value); // compare by identity == 比较
    }

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

    @Override
    public boolean equals(Object obj) {
        V value;
        return obj == this ||
               obj instanceof Value &&
               // cleared CacheValue is only equal to itself
               // 如果CacheValue已经无效(value被GC回收),则它只与自己相等。 == 比较
               (value = get()) != null &&
               value == ((Value<?>) obj).get(); // compare by identity ==比较
    }
}
(5) WeakCache.Factory类(重要)

从WeakCache的get方法可以看出,在代理类缓存不存在的情况下,会使用Factory生成代理类并包装为CacheValue,最后缓存在valueMap中。

// 生成代理类并包装为CacheValue,最后缓存在valueMap中
private final class Factory implements Supplier<V> {

    private final K key; // ClasLoader
    private final P parameter; // 代理接口数组
    private final Object subKey; // Key1、Key2、KeyX等实例
    private final ConcurrentMap<Object, Supplier<V>> valuesMap; // 根据subKey得到的valuesMap

    Factory(K key, P parameter, Object subKey,
            ConcurrentMap<Object, Supplier<V>> valuesMap) {
        this.key = key;
        this.parameter = parameter;
        this.subKey = subKey;
        this.valuesMap = valuesMap;
    }

    @Override
    public synchronized V get() { // serialize access 同步,串行获取
        // re-check 再次检查valuesMap中subKey对应的supplier是否已改变
        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 重试
          	// 因为get是同步方法,有可能是我们在等待的时候发生了如下事:
							1.其他线程生成了代理类并包装为CacheValue替换了当前的supplier或者
              2.因为生成代理类失败所以当前supplier被删除了见下面的代码
            return null;
        }
        // else still us (supplier == this) // supplier未改变

        // create new value // 创建代理类
        V value = null;
        try {
          	// 使用Proxy.ProxyClassFactory类生成代理类。若失败,则抛出空指针异常,退出
            value = Objects.requireNonNull(valueFactory.apply(key, parameter));
        } finally {
            if (value == null) { // remove us on failure 生成失败,移除该<subKey, Factory>映射
                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)) { // factory替换为CacheValue
            // put also in reverseMap
            reverseMap.put(cacheValue, Boolean.TRUE); // 更新reverseMap
        } else {
            throw new AssertionError("Should not reach here");
        }

        // successfully replaced us with new CacheValue -> return the value
        // wrapped by it
        return value; // 返回代理类
    }
}

这里valueFactory.apply(key, parameter)实际调用的是Proxy.ProxyClassFactory.apply方法。这个方法是生成代理类的关键所在。如下所示:

private static final class ProxyClassFactory
    implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
    // prefix for all proxy class names 代理类名的前缀
    private static final String proxyClassNamePrefix = "$Proxy";

    // next number to use for generation of unique proxy class names 代理类名构成的序号
    private static final AtomicLong nextUniqueNumber = new AtomicLong();

    @Override
    public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { // 生成代理类
				// interfaceSet用于检查interfaces是否存在重复接口
        Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
        for (Class<?> intf : interfaces) { // 遍历
            /*
             * Verify that the class loader resolves the name of this
             * interface to the same Class object.
             */
            Class<?> interfaceClass = null; // 验证ClassLoader能加载该接口
            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; // 访问标志 public 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.
         */
        // 1.记录非public接口的包名,然后代理类定义在相同的包名下
        // 2.验证所有非public的接口,都必须在同一个包下,否则抛出异常
        for (Class<?> intf : interfaces) {
            int flags = intf.getModifiers(); // 获取接口的访问标志
            if (!Modifier.isPublic(flags)) { // 若非public
                accessFlags = Modifier.FINAL; // 访问标志改为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) { // 若不存在非public的接口,则代理类定义在com.sun.proxy下
            // if no non-public proxy interfaces, use com.sun.proxy package
            proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; 
        }

        /*
         * Choose a name for the proxy class to generate.
         */
        long num = nextUniqueNumber.getAndIncrement();
        // e.g. com.sun.proxy.$Proxy0
        String proxyName = proxyPkg + proxyClassNamePrefix + num; // 代理类全限定类名

        /*
         * Generate the specified proxy class.
         */
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
            proxyName, interfaces, accessFlags); // 使用ProxyGenerator生产代理类的字节数组
        try {
        		// 在loader ClassLoader中定义该代理类
            return defineClass0(loader, proxyName,
                                proxyClassFile, 0, proxyClassFile.length);
        } catch (ClassFormatError e) {
            /*
             * A ClassFormatError here means that (barring bugs in the
             * proxy class generation code) there was some other
             * invalid aspect of the arguments supplied to the proxy
             * class creation (such as virtual machine limitations
             * exceeded).
             */
            throw new IllegalArgumentException(e.toString());
        }
    }
}
// Proxy的defineClass0方法
private static native Class<?> defineClass0(ClassLoader loader, String name,
                                                byte[] b, int off, int len);
4.生成代理类实例newProxyInstance

newProxyInstance方法的逻辑可分为两步:首先调用Proxy.getProxyClass0方法获取代理类,然后反射获取其构造器并生成代理类实例。

// 生成代理类实例,loader: 类加载器;interfaces: 代理接口;h: 调用处理器
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
                                      InvocationHandler h) throws IllegalArgumentException
{
    Objects.requireNonNull(h);

    final Class<?>[] intfs = interfaces.clone(); // 代理接口数组浅拷贝
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) { // 检查代理类创建权限
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
     * Look up or generate the designated proxy class.
     */
    Class<?> cl = getProxyClass0(loader, intfs); // 查找或创建代理类

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }

        final Constructor<?> cons = cl.getConstructor(constructorParams); // 获取构造器
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) { // 代理类非public
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true); // 设置访问权限
                    return null;
                }
            });
        }
        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);
    }
}
5.判断是否是代理类isProxyClass

判断一个类是否是动态代理类。

public static boolean isProxyClass(Class<?> cl) {
  	// 首先是要继承自Proxy,其次,缓存中必须存在
    return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}

判断WeakCache缓存中是否存在该类的细节:

// WeakCache.containsValue方法
public boolean containsValue(V value) { // 判断缓存中是否存在该类
    Objects.requireNonNull(value);

    expungeStaleEntries(); // 删除遗留的无效entry
  	// 使用LookupValue查找,避免创建CacheValue实例, == 比较
    return reverseMap.containsKey(new LookupValue<>(value));
}
// WeakCache.LookupValue类
private static final class LookupValue<V> implements Value<V> {
    private final V value;

    LookupValue(V value) {
        this.value = value;
    }

    @Override
    public V get() { // 返回value
        return value;
    }

    @Override
    public int hashCode() {
        return System.identityHashCode(value); // compare by identity == 比较
    } 

    @Override
    public boolean equals(Object obj) {
        return obj == this ||
               obj instanceof Value &&
               this.value == ((Value<?>) obj).get();  // compare by identity == 比较,重要
    }
}
6.获取InvocationHander实例getInvocationHandler
public static InvocationHandler getInvocationHandler(Object proxy) // proxy代理类实例
    throws IllegalArgumentException
{
    /*
     * Verify that the object is actually a proxy instance.
     */
    if (!isProxyClass(proxy.getClass())) { // 判断是否是代理类
        throw new IllegalArgumentException("not a proxy instance");
    }

    final Proxy p = (Proxy) proxy;
    final InvocationHandler ih = p.h; // InvocationHandler
    if (System.getSecurityManager() != null) {
        Class<?> ihClass = ih.getClass();
        Class<?> caller = Reflection.getCallerClass();
        if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
                                                ihClass.getClassLoader()))
        {
            ReflectUtil.checkPackageAccess(ihClass);
        }
    }

    return ih;
}

三、代理类生成的扩展知识点(细节)

1.ProxyGenerator生成代理类

ProxyClassFactory实际使用ProxyGenerator来生成代理类。

// 是否保存生成的代理类到文件,系统属性-Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true
private static final boolean saveGeneratedFiles =
        java.security.AccessController.doPrivileged(
            new GetBooleanAction(
                "jdk.proxy.ProxyGenerator.saveGeneratedFiles")).booleanValue();

// ProxyGenerator生成代理类的方法。name: 代理类名,interfaces:代理接口,accessFlags:访问标志
static byte[] generateProxyClass(final String name, Class<?>[] interfaces, int accessFlags)
{
    ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
    final byte[] classFile = gen.generateClassFile(); // 调用generateClassFile生成代理类

    if (saveGeneratedFiles) { // 保存代理类
        java.security.AccessController.doPrivileged(
        new java.security.PrivilegedAction<Void>() {
            public Void run() {
                try {
                    int i = name.lastIndexOf('.');
                    Path path;
                    if (i > 0) {
                        Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar));
                        Files.createDirectories(dir); // 创建目录
                        path = dir.resolve(name.substring(i+1, name.length()) + ".class");
                    } else {
                        path = Paths.get(name + ".class");
                    }
                    Files.write(path, classFile); // 写到文件
                    return null;
                } catch (IOException e) {
                    throw new InternalError(
                        "I/O exception saving generated file: " + e);
                }
            }
        });
    }

    return classFile;
}

generateProxyClass方法调用了ProxyGenerator.generateClassFile方法,生成代理类:

private byte[] generateClassFile() {

    /* ============================================================
     * Step 1: Assemble ProxyMethod objects for all methods to
     * generate proxy dispatching code for. 生成需要代理的所有方法的ProxyMethod对象
     */

    /*
     * Record that proxy methods are needed for the hashCode, equals,
     * and toString methods of java.lang.Object.  This is done before
     * the methods from the proxy interfaces so that the methods from
     * java.lang.Object take precedence over duplicate methods in the
     * proxy interfaces.
     */
  	// hashCode(), equals(), toString()方法的声明类是Object.class,且优先于代理接口中的这些方法定义
    addProxyMethod(hashCodeMethod, Object.class);
    addProxyMethod(equalsMethod, Object.class);
    addProxyMethod(toStringMethod, Object.class);

    /*
     * Now record all of the methods from the proxy interfaces, giving
     * earlier interfaces precedence over later ones with duplicate
     * methods.
     */
  	// 如果代理接口之中存在名称和参数签名相同的重复方法,则代理接口数组中排在前面的代理接口中的方法
  	// 定义优先于后面的接口,即方法的声明接口为前面的接口
    for (Class<?> intf : interfaces) {
        for (Method m : intf.getMethods()) {
            addProxyMethod(m, intf);
        }
    }

    /*
     * For each set of proxy methods with the same signature,
     * verify that the methods' return types are compatible.
     */
    for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
        checkReturnTypes(sigmethods); // 检查返回类型的兼容性
    }

    /* ============================================================
     * Step 2: Assemble FieldInfo and MethodInfo structs for all of
     * fields and methods in the class we are generating. 生成FieldInfo、MethodInfo
     */
    try {
        methods.add(generateConstructor());

        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
            for (ProxyMethod pm : sigmethods) {

                // add static field for method's Method object
                fields.add(new FieldInfo(pm.methodFieldName,
                    "Ljava/lang/reflect/Method;",
                     ACC_PRIVATE | ACC_STATIC));

                // generate code for proxy method and add it
                methods.add(pm.generateMethod());
            }
        }

        methods.add(generateStaticInitializer());

    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception", e);
    }

    if (methods.size() > 65535) {
        throw new IllegalArgumentException("method limit exceeded");
    }
    if (fields.size() > 65535) {
        throw new IllegalArgumentException("field limit exceeded");
    }

    /* ============================================================
     * Step 3: Write the final class file. 生成类文件
     */

    /*
     * Make sure that constant pool indexes are reserved for the
     * following items before starting to write the final class file.
     */
    cp.getClass(dotToSlash(className));
    cp.getClass(superclassName);
    for (Class<?> intf: interfaces) {
        cp.getClass(dotToSlash(intf.getName()));
    }

    /*
     * Disallow new constant pool additions beyond this point, since
     * we are about to write the final constant pool table.
     */
    cp.setReadOnly();

    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    DataOutputStream dout = new DataOutputStream(bout);

    try {
        /*
         * Write all the items of the "ClassFile" structure.
         * See JVMS section 4.1.
         */
                                    // u4 magic;
        dout.writeInt(0xCAFEBABE);
                                    // u2 minor_version;
        dout.writeShort(CLASSFILE_MINOR_VERSION);
                                    // u2 major_version;
        dout.writeShort(CLASSFILE_MAJOR_VERSION);

        cp.write(dout);             // (write constant pool)

                                    // u2 access_flags;
        dout.writeShort(accessFlags);
                                    // u2 this_class;
        dout.writeShort(cp.getClass(dotToSlash(className)));
                                    // u2 super_class;
        dout.writeShort(cp.getClass(superclassName));

                                    // u2 interfaces_count;
        dout.writeShort(interfaces.length);
                                    // u2 interfaces[interfaces_count];
        for (Class<?> intf : interfaces) {
            dout.writeShort(cp.getClass(
                dotToSlash(intf.getName())));
        }

                                    // u2 fields_count;
        dout.writeShort(fields.size());
                                    // field_info fields[fields_count];
        for (FieldInfo f : fields) {
            f.write(dout);
        }

                                    // u2 methods_count;
        dout.writeShort(methods.size());
                                    // method_info methods[methods_count];
        for (MethodInfo m : methods) {
            m.write(dout);
        }

                                     // u2 attributes_count;
        dout.writeShort(0); // (no ClassFile attributes for proxy classes)

    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception", e);
    }

    return bout.toByteArray(); // 返回字节数组
}
2.代理类文件

从上面的代码可以看出,设置jdk.proxy.ProxyGenerator.saveGeneratedFiles=true系统属性,即可生成代理类文件到本地。最后生成的文件如下所示:

package com.sun.proxy; // 代理接口都为public,则包名为com.sun.proxy;否则,为非public代理接口的包名

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import javabasiscode.Proxy.DynamicProxy.Subject;

public final class $Proxy0 extends Proxy implements Subject { // 继承自Proxy,实现代理接口
    private static Method m1; // 代理的方法
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  { // 唯一构造器,传入InvocationHandler
        super(var1);
    }

    public final boolean equals(Object var1) throws  { // 代理equals()
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  { // 代理toString()
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void request() throws  { // 代理接口的方法
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  { // 代理hashCode()
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("javabasiscode.Proxy.DynamicProxy.Subject").getMethod("request");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

参考文献