一、首先要讲动态代理,先要从代理模式讲起
// 定义公共接口
public interface IShop {
public void buy();
}
public class MyBuy implements IShop {
@Override
public void buy() {
System.out.print("真正的买东西");
}
}
public class Static implements IShop {
private IShop innerShop;
public Static(IShop innerShop) {
this.innerShop = innerShop;
}
@Override
public void buy() {
innerShop.buy();
}
}
Static s = new Static(new MyBuy());
s.buy();
上面就是代理模式的简单例子,代理模式的作用有两个,一个是为保护真正的是代码实现类,不让它直接暴露给客户,起一个中介的作用。另一个是可以在代理的过程,给代码的业务实现加点料,后者一般被拿来做程序员该做的事。
二、动态代理
上面这个代理,需要编译之前将代理类写好,打包成.class。而动态代理是在运行时,再生成相应的.class。
先来看动态代理的代码实现
public class Dynamic implements InvocationHandler {
private Object object;
public Dynamic(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(object, args);
}
}
IShop shop = new MyBuy();
Dynamic dynamic = new Dynamic(shop);
IShop proxy = (IShop) Proxy.newProxyInstance(shop.getClass().getClassLoader(), new Class[]{IShop.class}, dynamic);
proxy.buy();
核心的代码就是 Proxy.newProxyInstance()生成一个代理类,并返回它的对象
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
// 生成代理类的.class并获得对应的Class
Class<?> cl = getProxyClass0(loader, intfs);
try {
// 获得构造方法,并且这个构造方法有个参数为InvocationHandler
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//
if (!Modifier.isPublic(cl.getModifiers())) {
cons.setAccessible(true);
}
// 获得代理类的实例 等同于 Static s = new Static(new MyBuy());
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);
}
}
getProxyClass0()这个方法在运行时生成一个名为 公共接口的包名+前缀:“$Proxy"+累计的唯一编码的数字
class “$Proxy"+累计的唯一编码的数字 implements IShop{
InvocationHandler h;
public “$Proxy"+累计的唯一编码的数字(InvocationHandler h){
this.h = h;
...
}
@Override
public void buy() {
...
this.h.invoke(..);
}
}
当调用相应接口的方法时,就是调用到invoke方法
相关的源代码:
class Proxy{
...
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) {
/*
* 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;
// 获得包名
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;
return generateProxy(proxyName, interfaces, loader, methodsArray,
exceptionsArray);
}
}
}
...
}
具体生成.class的代码实现在native中实现,generateProxy是一个native方法,返回值为Class。在这个方法中做的事情,大概就是拼一个.class的二进制的文本,并加载进来。
以上就是动态代理的全部核心源代码实现(Java层),接下来解析其中一个重要的数据结构WeakCache
三、Weakcache
这个数据结构作用:当需要get(..)某个值时,首先在缓存中找,如果缓存中没有该值,便生成一个值,返回并放入缓存中。在缓存中使用弱引用的方式存储该值。
这个类的变量
final class WeakCache<K, P, V> {
private final ReferenceQueue<K> refQueue
= new ReferenceQueue<>(); // classLeader弱引用对应ReferenceQueue,用于更新map,删除以回收的key
// the key type is Object for supporting null key
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
= new ConcurrentHashMap<>(); // 主存储map,key值为外部传入classleader的弱引用,
value为以外部传入公共接口生成CacheKey和对应生成代理cLass<?>构成Map集合
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
= new ConcurrentHashMap<>(); // 用于存储代理Class<?>的弱引用的map,起标志作用
private final BiFunction<K, P, ?> subKeyFactory; // 通过外部传入的公共接口生成key值的工厂,
这个key用于上面map的value,即对应的ConcurrentMap
private final BiFunction<K, P, V> valueFactory; // 连接native生成代理CLass<?>的工厂
}
Weakcache.get(..)方法
class EakCache{
...
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
// 通过refQueue清理掉已经回收的Classleader
expungeStaleEntries();
// 通过对应的Classleader生成CacheKey,作为map的key,注意:CacheKey重写hash
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 从缓存中获得对应的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;
}
}
// 通过外部的接口,生成对应的suKey
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
// 从缓存中找是否有缓存好的代理Class<?>,即CacheValue对象
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
if (supplier != null) {
// 可能是Factory或CacheValue <V>实例
V value = supplier.get();
if (value != null) {
return value;
}
}
// 配置一个ProxyClassFactory,用于生成一个新的代理CLass<?>
if (factory == null) {
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
// 将对应的Factory放入,但在Factory的get方法中会调换
成代理Class<?>的CacheValue对象(后面说明)
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
supplier = factory;
}
} else {
// 更新
if (valuesMap.replace(subKey, supplier, factory)) {
supplier = factory;
} else {
// 如果替换失败,换回之前的
supplier = valuesMap.get(subKey);
}
}
}
}
...
}
上面提到的Factory源代码:
private final class Factory implements Supplier<V> {
private final K key;
private final P parameter; // 外部传入接口
private final Object subKey; // 外部传入接口生成的key
private final ConcurrentMap<Object, Supplier<V>> valuesMap; // map对应的value
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
// 如果缓存里有,直接使用
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
return null;
}
// 调用native生成新的代理Class<?>
V value = null;
try {
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);
// 将生成代理Class<?>CacheValue替换原来存进去的Factory
if (valuesMap.replace(subKey, this, cacheValue)) {
// 同时也存入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;
}
}