JDK动态代理源码深度解析 - 基于Proxy的接口代理机制
一、核心原理概述
JDK动态代理是JDK原生支持的代理机制,核心依赖接口与反射 实现。其底层逻辑是:通过 java.lang.reflect.Proxy 类动态生成一个实现目标接口的代理类(字节码),该代理类会将所有方法调用转发给 InvocationHandler 接口的实现类,最终由 InvocationHandler 完成对目标方法的增强与原始调用。 关键限制:JDK动态代理只能代理接口(代理类会实现目标接口),无法直接代理类(除非目标类实现了接口)。
二、核心API源码解析
JDK动态代理的入口是 Proxy.newProxyInstance() 方法,我们从该方法切入,逐步拆解源码流程。
2.1 入口方法:newProxyInstance()
scss
public static Object newProxyInstance(ClassLoader var0, Class<?>[] var1, InvocationHandler var2) throws IllegalArgumentException {
// 1. 校验InvocationHandler不能为空(核心回调,必须指定)
Objects.requireNonNull(var2);
// 2. 克隆接口数组:避免外部修改传入的接口数组,保证线程安全
Class[] var3 = (Class[])var1.clone();
// 3. 安全管理器检查(若开启,校验调用者是否有生成代理类的权限)
SecurityManager var4 = System.getSecurityManager();
if (var4 != null) {
checkProxyAccess(Reflection.getCallerClass(), var0, var3);
}
// 4. 核心步骤:获取/生成代理类的Class对象
Class var5 = getProxyClass0(var0, var3);
try {
// 5. 安全管理器再次检查(校验是否有实例化代理类的权限)
if (var4 != null) {
checkNewProxyPermission(Reflection.getCallerClass(), var5);
}
// 6. 获取代理类的构造器(参数为InvocationHandler.class)
final Constructor var6 = var5.getConstructor(constructorParams);
// 7. 若代理类非public,通过AccessController开放访问权限
if (!Modifier.isPublic(var5.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
var6.setAccessible(true);
return null;
}
});
}
// 8. 实例化代理类:传入InvocationHandler,返回代理对象
return var6.newInstance(var2);
} catch (InstantiationException | IllegalAccessException var8) {
throw new InternalError(var8.toString(), var8);
} catch (InvocationTargetException var9) {
Throwable var7 = var9.getCause();
if (var7 instanceof RuntimeException) {
throw (RuntimeException)var7;
} else {
throw new InternalError(var7.toString(), var7);
}
} catch (NoSuchMethodException var10) {
throw new InternalError(var10.toString(), var10);
}
}
关键流程拆解:
- 参数校验与克隆 :确保
InvocationHandler非空,克隆接口数组避免外部篡改; - 安全检查:兼容Java安全管理器,控制代理类的生成与实例化权限; - 核心逻辑 :通过
getProxyClass0()获取代理类,再通过构造器实例化(传入InvocationHandler)。
2.2 代理类缓存:getProxyClass0()
java
private static Class<?> getProxyClass0(ClassLoader var0, Class<?>... var1) {
// 限制:代理的接口数量不能超过65535(JVM类文件格式限制)
if (var1.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
} else {
// 从缓存中获取代理类:key为(类加载器 + 接口数组)
return (Class)proxyClassCache.get(var0, var1);
}
}
缓存设计核心:
proxyClassCache 是一个二级缓存(WeakCache),核心作用是避免重复生成代理类。因为: - 相同类加载器 + 相同接口组合,生成的代理类逻辑完全一致; - 缓存key由「类加载器」和「接口数组」组成,确保唯一性。
2.3 缓存获取逻辑:WeakCache.get()
java
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
// 清理过期缓存(弱引用相关)
expungeStaleEntries();
// 1. 生成一级缓存key(类加载器 + 引用队列)
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 2. 获取二级缓存(valuesMap):存储(子key -> 代理类Supplier)
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
if (valuesMap == null) {
// 若不存在,创建ConcurrentHashMap并放入一级缓存
ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// 3. 生成二级缓存key(接口数组相关)
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
// 4. 循环尝试获取代理类(处理并发场景)
while (true) {
if (supplier != null) {
// 若supplier存在,获取代理类(可能是缓存的实例或新生成)
V value = supplier.get();
if (value != null) {
return value;
}
}
// 5. 若supplier不存在,创建Factory(用于生成代理类)
if (factory == null) {
factory = new Factory(key, parameter, subKey, valuesMap);
}
// 6. 尝试将Factory放入二级缓存(CAS操作,保证并发安全)
if (supplier == null) {
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// 放入成功,使用当前Factory生成代理类
supplier = factory;
}
} else {
// 放入失败,替换原有supplier为Factory(重试)
if (valuesMap.replace(subKey, supplier, factory)) {
supplier = factory;
} else {
supplier = valuesMap.get(subKey);
}
}
}
}
缓存核心逻辑:
- 一级缓存(
map):key是CacheKey(类加载器 + 引用队列),value是二级缓存valuesMap; - 二级缓存(
valuesMap):key是subKey(接口数组相关),value是Supplier(代理类生成器); - 并发安全:通过
ConcurrentHashMap+ CAS操作(putIfAbsent、replace)保证多线程下缓存操作安全。
2.4 代理类生成:
- ProxyClassFactory.apply() 当缓存中无对应代理类时,
subKeyFactory(实际是ProxyClassFactory)的apply方法会生成代理类字节码并定义为Class对象。
java
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
// 1. 接口校验:确保接口可见性、是接口、无重复
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
// 校验1:接口必须能被当前类加载器加载(可见性)
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: " + loader);
}
// 校验2:必须是接口(JDK代理只能代理接口)
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface");
}
// 校验3:接口不能重复
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName());
}
}
// 2. 确定代理类的包名
String proxyPkg = null;
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
for (Class<?> intf : interfaces) {
// 若接口是非public的,代理类必须和接口同包(保证访问权限)
if (!Modifier.isPublic(intf.getModifiers())) {
accessFlags = Modifier.FINAL;
// 非public接口的代理类不能是public
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)) {
// 非public接口不能来自不同包
throw new IllegalArgumentException("non-public interfaces from different packages");
}
}
}
// 若所有接口都是public,代理类放入默认包:com.sun.proxy
if (proxyPkg == null) {
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
// 3. 生成代理类名:com.sun.proxy.$Proxy + 自增序号(如$Proxy0)
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// 4. 核心:生成代理类字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
try {
// 5. 定义代理类:通过native方法defineClass0将字节码加载为Class对象
return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
代理类生成关键步骤:
- 接口校验:确保接口合法(可见、是接口、无重复);
-
- 包名与类名 :非public接口同包,public接口用默认包,类名按
$Proxy+序号生成;
- 包名与类名 :非public接口同包,public接口用默认包,类名按
- 字节码生成 :
ProxyGenerator.generateProxyClass()生成代理类字节码(核心逻辑,底层是字节码拼接); - 类加载 :通过
defineClass0(native方法)将字节码加载为JVM可识别的Class对象。
三、模拟生成JDK代理类源码
JDK动态代理生成的代理类本质是「实现目标接口 + 继承Proxy类」的子类,所有接口方法都会转发给 InvocationHandler.invoke()。以下是模拟代码(以代理 UserService 接口为例):
目标接口:UserService.java
java
public interface UserService {
void addUser(String username); String getUserById(Integer id);
}
模拟代理类:$Proxy0.java
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/**
* JDK动态代理生成的代理类模拟(实际由JVM动态生成,并非手动编写)
*/
public final class $Proxy0 extends Proxy implements UserService {
// 缓存目标接口的方法(避免每次反射获取)
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m4;
private static Method m0;
// 构造器:接收InvocationHandler(必须与Proxy类的构造器一致)
public $Proxy0(InvocationHandler invocationHandler) {
super(invocationHandler);
}
// 重写Object类的equals方法(代理类会代理所有接口方法+Object的equals/hashCode/toString)
public final boolean equals(Object object) {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{object});
} catch (RuntimeException | Error runtimeException) {
throw runtimeException;
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final String toString() {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error runtimeException) {
throw runtimeException;
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
// 代理UserService的addUser方法
public final void addUser(String string) {
try {
// 核心:转发给InvocationHandler.invoke()
super.h.invoke(this, m3, new Object[]{string});
} catch (RuntimeException | Error runtimeException) {
throw runtimeException;
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
// 代理UserService的getUserById方法
public final String getUserById(Integer integer) {
try {
return (String)super.h.invoke(this, m4, new Object[]{integer});
} catch (RuntimeException | Error runtimeException) {
throw runtimeException;
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode() {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error runtimeException) {
throw runtimeException;
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
// 静态代码块:初始化方法缓存(类加载时执行)
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.example.UserService").getMethod("addUser", Class.forName("java.lang.String"));
m4 = Class.forName("com.example.UserService").getMethod("getUserById", Class.forName("java.lang.Integer"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException noSuchMethodException) {
throw new NoSuchMethodError(noSuchMethodException.getMessage());
} catch (ClassNotFoundException classNotFoundException) {
throw new NoClassDefFoundError(classNotFoundException.getMessage());
}
}
}
模拟类核心特点:
- 继承
Proxy类(持有InvocationHandler引用h); - 实现目标接口(
UserService); - 缓存所有方法(避免每次反射获取,提升性能);
- 所有方法调用最终转发给
h.invoke(this, method, args)。
四、JDK动态代理总结
- 核心依赖:接口 + 反射 + 字节码动态生成;
- 代理类特性 :继承
Proxy、实现目标接口、方法转发给InvocationHandler; - 缓存设计 :通过
WeakCache缓存代理类,避免重复生成; - 限制:只能代理接口,无法代理无接口的类;
- 性能:反射调用有一定开销,但缓存方法后性能可接受。
CGLIB动态代理源码解析 - 基于Enhancer的继承代理机制
一、核心原理概述 CGLIB(Code Generation Library)是一个基于ASM字节码框架的动态代理库,
核心依赖继承 实现。其底层逻辑是:通过 Enhancer 类动态生成目标类的子类,重写目标类的非final方法,将方法调用转发给 MethodInterceptor 接口的实现类,最终完成方法增强。 关键优势:无需目标类实现接口,可直接代理类(只要目标类非final、方法非final),弥补了JDK动态代理的限制。
二、核心API源码解析
CGLIB动态代理的核心是 Enhancer 类,我们从其核心配置方法和实例化方法切入,拆解源码流程。
2.1 核心配置:setSuperclass()
- 设置父类(目标类)
java
public void setSuperclass(Class superclass) {
if (superclass != null && superclass.isInterface()) {
// 若传入的是接口,转为设置接口(兼容接口代理场景)
this.setInterfaces(new Class[]{superclass});
this.setContextClass(superclass);
} else if (superclass != null && superclass.equals(Object.class)) {
// 若父类是Object,直接设为null(CGLIB对Object代理有默认处理)
this.superclass = null;
} else {
// 正常设置目标类为父类(核心:代理类将继承该类)
this.superclass = superclass;
this.setContextClass(superclass);
}
}
关键逻辑:
- CGLIB的核心是「继承代理」,因此
setSuperclass()是最关键的配置(指定目标类为父类); - 兼容接口代理:若传入接口,自动转为
setInterfaces()(但CGLIB更常用於类代理); - 限制:目标类不能是final(否则无法继承),方法不能是final(否则无法重写)。
2.2 核心配置:setCallback()
- 设置回调(增强逻辑)
java
public void setCallback(Callback callback) {
// 包装为回调数组(CGLIB支持多回调,setCallback是简化版)
this.setCallbacks(new Callback[]{callback});
}
关键说明:
Callback是CGLIB的回调接口,常用实现类是MethodInterceptor(方法拦截器); - 多回调支持:setCallbacks()可传入多个回调,通过CallbackFilter指定不同方法使用不同回调; - 核心作用:代理类的方法调用会转发给Callback实现类(如MethodInterceptor.intercept())。
2.3 实例化入口:create()
java
public Object create() { // 标记:不仅生成Class,还要实例化对象
this.classOnly = false;
// 构造器参数类型:默认无参构造
this.argumentTypes = null;
// 核心:调用createHelper()生成实例
return this.createHelper();
}
2.4 实例化辅助:createHelper()
java
private Object createHelper() {
// 1. 前置校验:检查配置是否合法(如父类是否final、回调是否设置等)
this.preValidate();
// 2. 生成缓存key:基于父类、接口、回调类型等关键参数
Object key = KEY_FACTORY.newInstance(
this.superclass != null ? this.superclass.getName() : null,
ReflectUtils.getNames(this.interfaces),
this.filter == ALL_ZERO ? null : new WeakCacheKey(this.filter),
this.callbackTypes,
this.useFactory,
this.interceptDuringConstruction,
this.serialVersionUID
);
this.currentKey = key;
// 3. 调用父类(AbstractClassGenerator)的create方法生成实例
Object result = super.create(key);
return result;
}
关键流程拆解:
- 前置校验 :
preValidate()检查父类非final、回调非空等核心配置; - 缓存key生成:KEY_FACTORY(CGLIB生成的工厂类)基于「父类名、接口名、回调类型、过滤器」等参数生成唯一key,用于缓存代理类;
- 父类create方法 :
AbstractClassGenerator.create()是核心,负责生成代理类字节码、加载类、实例化对象。
2.5 缓存与字节码生成(AbstractClassGenerator.create())
CGLIB的缓存逻辑与JDK类似,核心是「避免重复生成代理类」。AbstractClassGenerator 的 create() 方法会:
- 从缓存中根据key获取代理类;
- 若缓存不存在,通过ASM框架生成代理类字节码;
- 调用
ClassLoader加载代理类; - 通过反射实例化代理类(调用无参构造或指定构造);
- 将代理类放入缓存,返回实例。
核心差异(与JDK代理):
-
JDK代理生成的类实现接口,CGLIB生成的类继承目标类;
-
JDK依赖JVM原生字节码生成,CGLIB依赖ASM框架手动拼接字节码;
-
JDK代理转发给
InvocationHandler,CGLIB转发给MethodInterceptor。三、模拟生成CGLIB代理类源码
CGLIB动态代理生成的代理类是「目标类的子类」,重写所有非final方法,通过
MethodInterceptor实现增强。以下是模拟代码(以代理UserService类为例):目标类:UserService.java
java
/**
* 无接口的目标类(CGLIB可直接代理)
*/
public class UserService {
public void addUser(String username) {
System.out.println("目标方法:添加用户 -> " + username);
}
public String getUserById(Integer id) {
System.out.println("目标方法:查询用户 -> " + id);
return "用户" + id;
}
}
模拟代理类:EnhancerByCGLIB.java
java
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* CGLIB动态代理生成的代理类模拟(实际由ASM框架动态生成)
*/
public class EnhancerByCGLIB extends UserService {
// CGLIB生成的方法代理对象(优化反射调用)
private MethodProxy CGLIB$addUser$0$Proxy;
private MethodProxy CGLIB$getUserById$1$Proxy;
// 回调对象(MethodInterceptor)
private MethodInterceptor CGLIB$CALLBACK_0;
// 静态代码块:初始化方法代理(ASM生成时自动填充)
static {
try {
// 初始化方法代理:绑定目标方法与代理方法
Method addUserMethod = UserService.class.getMethod("addUser", String.class);
Method addUserProxyMethod = UserService$$EnhancerByCGLIB$$123456.class.getMethod("CGLIB$addUser$0", String.class);
CGLIB$addUser$0$Proxy = MethodProxy.create(
UserService.class,
UserService$$EnhancerByCGLIB$$123456.class,
"(Ljava/lang/String;)V",
addUserMethod.getName(),
addUserProxyMethod.getName()
);
Method getUserByIdMethod = UserService.class.getMethod("getUserById", Integer.class);
Method getUserByIdProxyMethod = UserService$$EnhancerByCGLIB$$123456.class.getMethod("CGLIB$getUserById$1", Integer.class);
CGLIB$getUserById$1$Proxy = MethodProxy.create(
UserService.class,
UserService$$EnhancerByCGLIB$$123456.class,
"(Ljava/lang/Integer;)Ljava/lang/String;",
getUserByIdMethod.getName(),
getUserByIdProxyMethod.getName()
);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
// 设置回调(Enhancer通过反射调用该方法注入MethodInterceptor)
public void setCallback(MethodInterceptor callback) {
this.CGLIB$CALLBACK_0 = callback;
}
// 重写目标类的addUser方法(核心:转发给MethodInterceptor)
@Override
public void addUser(String username) {
MethodInterceptor callback = this.CGLIB$CALLBACK_0;
if (callback != null) {
// 调用拦截器:参数(代理对象、目标方法、方法参数、方法代理)
callback.intercept(this, CGLIB$addUser$0$Proxy.getOriginalMethod(), new Object[]{username}, CGLIB$addUser$0$Proxy);
} else {
// 无回调时,直接调用父类(目标类)方法
super.addUser(username);
}
}
// 重写目标类的getUserById方法
@Override
public String getUserById(Integer id) {
MethodInterceptor callback = this.CGLIB$CALLBACK_0;
if (callback != null) {
try {
return (String) callback.intercept(
this,
CGLIB$getUserById$1$Proxy.getOriginalMethod(),
new Object[]{id},
CGLIB$getUserById$1$Proxy
);
} catch (Throwable e) {
throw new RuntimeException(e);
}
} else {
return super.getUserById(id);
}
}
// CGLIB生成的代理方法(内部使用,无需外部调用)
public void CGLIB$addUser$0(String username) {
super.addUser(username);
}
public String CGLIB$getUserById$1(Integer id) {
return super.getUserById(id);
}
}
模拟类核心特点:
- 继承目标类(
UserService),重写所有非final方法; - 持有
MethodProxy对象(CGLIB优化反射,通过FastClass机制提升调用性能); - 持有
MethodInterceptor回调对象,方法调用转发给intercept() - 提供
setCallback()方法,供Enhancer注入回调。
四、CGLIB动态代理总结
- 核心依赖:继承 + ASM字节码框架 + MethodInterceptor;
- 代理类特性 :继承目标类、重写非final方法、通过
MethodProxy优化调用; - 缓存设计:基于「父类、接口、回调类型」等参数缓存代理类,避免重复生成;
- 优势 :无需目标类实现接口,支持类代理;通过FastClass机制优化反射性能; 5. 限制:目标类不能是final,方法不能是final(否则无法继承/重写);