动态代理源码分析
2021-03-18 本文已影响0人
风月寒
动态代理步骤
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
4.通过代理调用方法
IRoom xiaoMing = new XiaoMing();
InvocationHandler invocationHandler = new DynamicProxy(xiaoMing);
ClassLoader classLoader = xiaoMing.getClass().getClassLoader();
IRoom proxy = (IRoom) Proxy.newProxyInstance(classLoader,new Class[]{IRoom.class},invocationHandler);
proxy.seekRoom();
proxy.watchRoom();
proxy.room();
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object,args);
return result;
}
}
通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象。
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);//1
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
cons.setAccessible(true);//2
}
return cons.newInstance(new Object[]{h});//3
}
}
先对h进行判空处理。
从1可知,先接口得到接口类,
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
return proxyClassCache.get(loader, interfaces);
}
当接口的数量超过65535,则报异常。
proxyClassCache 是一个弱引用的缓存
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
继续看它的get();
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
expungeStaleEntries();
//把key封装成CacheKey
Object cacheKey = CacheKey.valueOf(key, refQueue);
//通过CacheKey得到valuesMap
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
if (valuesMap == null) {
//如果valuesMap不存在通过全局map获取,如果获取到的直接赋值给valueMap
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
//根据subKey得到supplier
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
//如果supplier不为null,则直接调用get()获取
if (supplier != null) {
V value = supplier.get();
if (value != null) {
return value;
}
}
//为null的情况下,new 一个Factory。Factory是实现Supplier接口。
if (factory == null) {
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
supplier = factory;
}
} else {
if (valuesMap.replace(subKey, supplier, factory)) {
supplier = factory;
} else {
supplier = valuesMap.get(subKey);
}
}
}
}
接下来看supplier的get()
public synchronized V get() {
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
return null;
}
V value = null;
try {
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}
CacheValue<V> cacheValue = new CacheValue<>(value);
if (valuesMap.replace(subKey, this, cacheValue)) {
reverseMap.put(cacheValue, Boolean.TRUE);
} else {
throw new AssertionError("Should not reach here");
}
return value;
}
首先看proxyClassCache的定义WeakCache<ClassLoader, Class<?>[], Class<?>>,泛型里面第一个表示加载器K,第二个表示接口类P,第三个则是生成的代理类V。
而V的生成则是通过ProxyClassFactory生成的。调用其apply();
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
////将所有的接口对象都存到map中,并且不能有重复
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; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
//记录非公共代理接口的包,以便代理类将在同一个包中定义。确认所有非公共代理接口都在同一个包中。
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
//如果不是public修饰,则accessFlags设置为final
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 = "";
}
{
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()][]);
//生成代理的类名格式为:包名+"$Proxy"+随机数字
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
//调用native方法生成代理类
return generateProxy(proxyName, interfaces, loader, methodsArray,
exceptionsArray);
}
}
然后调用getMethod(),将equals(),hashcode(),toString()等方法添加进去。然后遍历所有接口的方法,添加到代理类中。最后将这些方法进行排序。
private static List<Method> getMethods(Class<?>[] interfaces) {
List<Method> result = new ArrayList<Method>();
try {
result.add(Object.class.getMethod("equals", Object.class));
result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
} catch (NoSuchMethodException e) {
throw new AssertionError();
}
getMethodsRecursive(interfaces, result);
return result;
}
private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
for (Class<?> i : interfaces) {
getMethodsRecursive(i.getInterfaces(), methods);
Collections.addAll(methods, i.getDeclaredMethods());
}
}
然后回到最初的1处,生成代理类返回。
在2处通过生成的代理类采用反射的方式得到其构造函数。
如果代理类不是public修饰,则cons.setAccessible(true);
在3处调用newInstance生成代理对象。
微信图片_20210318201503.jpg