这只是我研究java proxy写的小例子,代码不是那么规范。
代码应该都能看懂不说明了。
一小例子
public class o {
public static void main(String[] args) throws Exception {
face f= (face)Proxy.newProxyInstance(o.class.getClassLoader(), new Class[]{
face.class}, new InvocationHandler() {
face f=new imp();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("proxy------------------");
Object o=method.invoke(f, args[0].toString());
return o;
}
});
System.out.println(f.a("dddd"));
}
interface face{
String a(String canshu);
}
class imp implements face{
@Override
public String a(String canshu) {
// TODO Auto-generated method stub
System.out.println(canshu);
return "imp";
}
}
接下来研究一下怎么查看生成的的类信息。
进入Proxy.newProxyInstance()方法,我们只用关心生成class的方法,其他的不用看,反正我看也看不懂。
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
继续进入调用了ProxyClassFactory的 public Class> apply(ClassLoader loader, Class>[] interfaces) 方法里面主要的是
//生成字节信息
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//这是根据字节生成class实例
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
}
现在找到关键的代码了我们自己调一下就行
public static void main(String[] args) throws Exception {
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
"com.example.demo.proxy1", new Class[]{
face.class}, 1);//类路径,class,1表示public
FileOutputStream fo=new FileOutputStream("C:\\Users\\Administrator.DESKTOP-3U5OF5D\\Desktop\\proxy1.class");
fo.write(proxyClassFile);
}
最后用反编译工具看一下,我用的是idea自带的
package com.example.demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public class proxy1 extends Proxy implements face {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public proxy1(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{
var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String a(String var1) throws {
try {
return (String)super.h.invoke(this, m3, new Object[]{
var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
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.demo.face").getMethod("a", Class.forName("java.lang.String"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
看到生成的类继承了proxy,所以说java代理是基于接口的因为java是单继承。(还有一种cglib可以根据字节码增强)。
生成的类也没什么说的了,就是构造方法传入一个我们自己的InvocationHandler,再定义Method属性代表代理对象拥有的方法。然后调用invoke。