ContactService.java
public interface ContactService {
void contact(String userId);
}
ContactServiceImpl.java
public class ContactServiceImpl implements ContactService{
public void contact(String userId) {
System.out.println("contact with " + userId);
}
}
JdkProxy.java
public class JdkProxy {
public static void main(String args[]){
final ContactService contactService = new ContactServiceImpl();
ContactService contactServiceProxy = (ContactService) Proxy
.newProxyInstance(JdkProxy.class.getClassLoader()
, new Class[] {ContactService.class}
, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy begin...");
String proxySimpleClassName = proxy.getClass().getSimpleName();
byte[] proxyClassByteArray = ProxyGenerator.generateProxyClass(
proxySimpleClassName, proxy.getClass().getInterfaces());
FileOutputStream fos = null;
try{
fos = new FileOutputStream(proxySimpleClassName + ".class");
fos.write(proxyClassByteArray);
fos.flush();
}finally {
if(fos != null){
fos.close();
}
}
return method.invoke(contactService, args);
}
});
contactServiceProxy.contact("nafoahnaw");
}
}
以上代码关键之一在于代理对象contactServiceProxy是如何生成的
要知道这点必须继续深入源码,java.lang.reflect.Proxy#newProxyInstance的关键步骤
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
/**
* Generate a proxy class. Must call the checkProxyAccess method
* to perform permission checks before calling this.
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// If the proxy class defined by the given loader implementing
// the given interfaces exists, this will simply return the cached copy;
// otherwise, it will create the proxy class via the ProxyClassFactory
return proxyClassCache.get(loader, interfaces);
}
getProxyClass0方法基于WeakCache实现,WeakCache也是一个类Map的结构
/**
* a cache of proxy classes
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
通过注释和proxyClassCache我们发现ProxyClassFactory是产生代理对象class类的关键
继续深入java.lang.reflect.Proxy.ProxyClassFactory#apply方法,关键代码如下
/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
这样就根据newProxyInstance方法中给出的interfaces创建出了代理对象,继续回到java.lang.reflect.Proxy#newProxyInstance方法,cl就是contactServiceProxy的class对象,通过cl.getConstructor获取构造函数然后生成对象。
/** parameter types of a proxy class constructor */
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
这里其实有点困惑,cl里为什么会存在一个参数为InvocationHandler的构造函数?回到ProxyClassFactory方法
/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
代理对象Class对象的具体类定义由ProxyGenerator.generateProxyClass方法给出,通过走读sun.misc.ProxyGenerator#generateClassFile源码我们可以发现,sun.misc.ProxyGenerator#generateConstructor是此方法给我们生成的代理对象加上了该构造方法,sun.misc.ProxyGenerator#generateClassFile方法为代理对象继承了Proxy类,关键代码如下
var14.writeInt(-889275714);
var14.writeShort(0);
var14.writeShort(49);
this.cp.write(var14);
var14.writeShort(this.accessFlags);
var14.writeShort(this.cp.getClass(dotToSlash(this.className)));
var14.writeShort(this.cp.getClass("java/lang/reflect/Proxy"));
var14.writeShort(this.interfaces.length);
private ProxyGenerator.MethodInfo generateConstructor() throws IOException {
ProxyGenerator.MethodInfo var1 = new ProxyGenerator.MethodInfo("<init>", "(Ljava/lang/reflect/InvocationHandler;)V", 1);
DataOutputStream var2 = new DataOutputStream(var1.code);
this.code_aload(0, var2);
this.code_aload(1, var2);
var2.writeByte(183);
var2.writeShort(this.cp.getMethodRef("java/lang/reflect/Proxy", "<init>", "(Ljava/lang/reflect/InvocationHandler;)V"));
var2.writeByte(177);
var1.maxStack = 10;
var1.maxLocals = 2;
var1.declaredExceptions = new short[0];
return var1;
}
那么在运行是生成出来的contactServiceProxy对象究竟长啥样呢,我们可以运行最上面的代码,将contactServiceProxy写入到文件中通过idea反编译来看,关键代码如下
public final class $Proxy0 extends Proxy implements ContactService {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("service.ContactService").getMethod("contact", Class.forName("java.lang.String"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
public final void contact(String var1) throws {
try {
//这个h就是我们匿名构造的InvocationHandler,从Proxy类继承而来
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}