JDK 动态代理源码分析

本文将探讨JDK动态代理的工作原理,通过分析`Proxy.newProxyInstance()`的源码,揭示如何实现接口动态代理。核心在于`WeakCache`中的`KeyFactory`和`ProxyClassFactory`,它们分别用于生成Key和代理类Class对象。动态代理类在首次生成时,由`ProxyClassFactory.apply()`方法完成,该方法调用`ProxyGenerator.generateProxyClass()`生成包含所有接口方法和特定构造器的字节码,构造器接收`InvocationHandler`作为参数。
摘要由CSDN通过智能技术生成

JDK动态代理,通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的方法,来实现代理。 

代码入口Proxy.newProxyInstance():

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
	//handler 对象不能是空
	Objects.requireNonNull(h);

	//被代理对象实现的所有接口
	final Class<?>[] intfs = interfaces.clone();
	
	//安全控制,可以不用管
	final SecurityManager sm = System.getSecurityManager();
	if (sm != null) {
		checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
	}

	/*
	 * Look up or generate the designated proxy class.
	 */
	//生成指定的代理对象的类,这个才是重点方法
	Class<?> cl = getProxyClass0(loader, intfs);

	/*
	 * Invoke its constructor with the designated invocation handler.
	 */
	try {
		if (sm != null) {
			checkNewProxyPermission(Reflection.getCallerClass(), cl);
		}

		final Constructor<?> cons = cl.getConstructor(constructorParams);
		final InvocationHandler ih = h;
		
		//如果代理对象的类或者修饰符不是 public 的, 执行 PrivilegedAction.run 方法。这里设置当前构造函数为访问权限
		if (!Modifier.isPublic(cl.getModifiers())) {
			//启用特权,执行指定的 PrivilegedAction。
			AccessController.doPrivileged(new PrivilegedAction<Void>() {
				public Void run() {
					cons.setAccessible(true);
					return null;
				}
			});
		}
		
		//使用 InvocationHandler 作为参数调用构造方法来获得代理类的实例  
		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);
	}
}//生成指定的代理对象的类,这个才是重点方法
	Class<?> cl = getProxyClass0(loader, intfs);

	/*
	 * Invoke its constructor with the designated invocation handler.
	 */
	try {
		if (sm != null) {
			checkNewProxyPermission(Reflection.getCallerClass(), cl);
		}

		final Constructor<?> cons = cl.getConstructor(constructorParams);
		final InvocationHandler ih = h;
		
		//如果代理对象的类或者修饰符不是 public 的, 执行 PrivilegedAction.run 方法。这里设置当前构造函数为访问权限
		if (!Modifier.isPublic(cl.getModifiers())) {
			//启用特权,执行指定的 PrivilegedAction。
			AccessController.doPrivileged(new PrivilegedAction<Void>() {
				public Void run() {
					cons.setAccessible(true);
					return null;
				}
			});
		}
		
		//使用 InvocationHandler 作为参数调用构造方法来获得代理类的实例  
		return cons.newInstance(new Object[]{h});
		
	} catch (IllegalAccessException|InstantiationException e) {
		throw
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值