概述
-
Proxy
提供静态方法来创建动态代理类和动态代理对象; - 源码基于 Android-SDK-29 中的 JDK;
动态代理类
- 动态代理类的父类是
Proxy
,并且实现了动态创建时指定的接口;类名不是明确的,以$Proxy
开头; - 如果代理接口都是
public
,那么动态代理类是public
final
的,不是abstract
;如果代理接口中有任意一个是not public
,那么动态代理类是not public
final
的,不是abstract
,动态代理类所在的包和not public
代理接口所在的包一致; - 每个动态代理类有一个
public
的构造函数,该构造函数只有一个InvocationHandler
类型的参数; - 如果一个具有相同排列的代理接口的动态代理类已经被一个
ClassLoader
定义了,就不会重复生成新的动态代理类
动态代理对象
- 动态代理对象是动态代理类的实例,动态代理类的构造方法是只有一个
InvocationHandler
类型的参数; - 动态代理对象的所有方法调用,包括
hashCode
equals
toString
,以及代理接口的方法调用,都是转发给关联的InvocationHandler
对象实现的;
源码
- InvocationHandler
protected InvocationHandler h; protected Proxy(InvocationHandler h) { Objects.requireNonNull(h); this.h = h; } public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
- 每个动态代理对象都绑定一个
InvocationHandler
对象,动态代理对象的所有方法调用,都要转发给InvocationHandler#invoke
;
- 每个动态代理对象都绑定一个
-
getProxyClass
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } return proxyClassCache.get(loader, interfaces); }
- 如果指定的
ClassLoader
已经定义了相同排列的代理接口的动态代理类,那么直接返回;否则,动态生成类;
- 如果指定的
-
newProxyInstance
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone(); //生成动态代理类 Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { //动态代理类的构造函数 final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { cons.setAccessible(true); } //创建动态代理对象 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); } }
- 先生成对应的动态代理类,再通过构造函数生成动态代理对象;
-
isProxyClass
public static boolean isProxyClass(Class<?> cl) { return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl); }
- 判断是否是动态代理类;
网友评论