动态代理原理

动态代理(JDK或接口代理)

参考: https://www.bilibili.com/video/BV1V4411W7xy?p=4
在这里插入图片描述

IHello iHello = (IHello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),
                hello.getClass().getInterfaces(),
                handler);

newProxyInstance:

  • 在JVM里生成字节码,字节码加载后生成Class对象
/*
 * Look up or generate the designated proxy class.
 */
Class<?> cl = getProxyClass0(loader, intfs);

getProxyClass0:

private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
	// 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);
}

proxyClassCache.get:

先从缓存ConcurrentMap<>中查找是否存在

		Objects.requireNonNull(parameter);

        expungeStaleEntries();

        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // 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) {
                valuesMap = oldValuesMap;
            }
        }

创建:

Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));

其中subKeyFactory是BiFunction(Interface),具体实现类是:

private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>

其中实现的apply方法,其中阐述了$Proxy的由来。

public Class<?> apply(ClassLoader loader, Class<?>[] interfaces)
private static final String proxyClassNamePrefix = "$Proxy";
/*
 * Choose a name for the proxy class to generate.
 */
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;

在内存中直接生成了java字节码(.class),该类方法的源码从jdk1.6后就不开源:

/*
 * Generate the specified proxy class.
 */
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
    proxyName, interfaces, accessFlags);

随后通过字节码拿到对象,这个方法也是一个native本地方法:

return defineClass0(loader, proxyName,
                    proxyClassFile, 0, proxyClassFile.length);

深入proxyClassFile:

利用反编译工具进入,$Proxy0进入硬盘

public final class $Proxy0 extends Proxy implements AaFactory{
    // h指invocationHandler
	h.invoke
    // 最终调用了实现类中invoke方法
}
/**
	拿到对象constructor后创建handler相关联的代理实例
*/
final Constructor<?> cons = cl.getConstructor(constructorParams);
return cons.newInstance(new Object[]{h});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值