基于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; public class ProxyHandlerimplements 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); } } }
输出
3. 原理解析before invoke…
2021-11-08T16:26:51.428 动态代理demo
after invoke…
父类:class java.lang.reflect.Proxy
实现接口:interface org.example.proxy.RecordLog
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[], 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{ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); ConcurrentMap



