基于java 8说明
1. JDK动态代理
JDK动态代理由java.lang.reflect.Proxy
类实现,java.lang.reflect.Proxy
对象持有一个 java.lang.reflect.InvocationHandler
对象,而java.lang.reflect.InvocationHandler
对象又持有目标对象;使用时,需要实现InvocationHandler接口(代理的具体逻辑在invoke方法中实现),然后通过java.lang.reflect.Proxy.newProxyInstance
等方法生成com.sun.proxy.$Proxy
代理对象,来完成对目标对象的调用。
2. 代码示例
package org.example.proxy;
/**
* 目标接口
*/
public interface RecordLog {
void add(String log);
}
package org.example.proxy;
import java.time.LocalDateTime;
/**
* 目标接口实现
*/
public class RecordLogImpl implements RecordLog {
@Override
public void add(String log) {
System.out.println(LocalDateTime.now() + " " + log);
}
}
package org.example.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* InvocationHandler实现
*/
public class ProxyHandler<T> implements InvocationHandler {
private T target;
public ProxyHandler(T target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 添加自己的操作
System.out.println("before invoke...");
Object result = method.invoke(target, args);
// 添加自己的操作
System.out.println("after invoke...");
return result;
}
public static void main(String[] args) {
// 目标对象
RecordLog target = new RecordLogImpl();
// InvocationHandler对象
InvocationHandler handler = new ProxyHandler<>(target);
// 获取代理对象
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
// 执行代理
((RecordLog) proxy).add("动态代理demo");
// 输出代理对象的父类和接口
System.out.println("父类:" + proxy.getClass().getSuperclass());
for (Class<?> anInterface : proxy.getClass().getInterfaces()) {
System.out.println("实现接口:" + anInterface);
}
}
}
输出
before invoke…
2021-11-08T16:26:51.428 动态代理demo
after invoke…
父类:class java.lang.reflect.Proxy
实现接口:interface org.example.proxy.RecordLog
3. 原理解析
Proxy.newProxyInstance方法会返回一个com.sun.proxy.$Proxy0
对象,该对象继承了java.lang.reflect.Proxy
类,并且实现了目标接口(JDK动态代理通过实现目标接口的方式来完成对目标对象的代理,所以要求目标对象必须实现接口),生成动态代理类的核心代码在java.lang.reflect.ProxyClassFactory
类中。
package java.lang.reflect;
public class Proxy implements java.io.Serializable {
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h){
// ...此处省略代码
// 获取动态代理类 com.sun.proxy.$Proxy0
Class<?> cl = getProxyClass0(loader, intfs);
try {
// ...此处省略代码
final Constructor<?> cons = cl.getConstructor(constructorParams);
// ...此处省略代码
// 生成代理对象
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);
}
}
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 此处调用了java.lang.reflect.WeakCache中的get方法,优先从缓存中获取动态代理类,但最终会调用到ProxyClassFactory.apply方法生成代理类
return proxyClassCache.get(loader, interfaces);
}
// 代理类工厂,用于生成并返回动态代理类
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// ...此处省略代码
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
// ...此处省略代码
// 生成动态代理类的class文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
// defineClass0 是一个native方法,定义了动态代理类
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
}
package java.lang.reflect;
final class WeakCache<K, P, V> {
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
expungeStaleEntries();
Object cacheKey = CacheKey.valueOf(key, refQueue);
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;
}
}
// 获取缓存的key值,subKeyFactory为java.lang.reflect.KeyFactory对象
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
if (supplier != null) {
// supplier为java.lang.reflect.Factory对象,此处调用Factory.get()方法获取动态代理类 com.sun.proxy.$Proxy0
V value = supplier.get();
if (value != null) {
return value;
}
}
// 获取java.lang.reflect.Factory对象
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);
}
}
}
}
private final class Factory implements Supplier<V> {
// ...此处省略代码
@Override
public synchronized V get() {
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
return null;
}
V value = null;
try {
// java.lang.reflect.ProxyClassFactory中的apply方法生成了动态代理类,ProxyClassFactory是Proxy类的内部类
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) {
valuesMap.remove(subKey, this);
}
}
assert value != null;
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;
}
}
}