自身理解,如有错误,欢迎指正!
首先贴代码:模拟黄牛代理员工买票
public interface People {
void buyTicket(int i);
}
public class Employee implements People {
@Override
public void buyTicket(int i) {
System.out.println("北京 -》 上海");
}
}
public class Scalper implements InvocationHandler {
/**
* 被代理对象
*/
private Object target;
/**
* 获取代理对象
* @param target
* @return
*/
public Object getProxy(Object target){
this.target = target;
Class<?> clazz = target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("获取所有票");
Object o = method.invoke(target, args);
System.out.println("获取符合的票");
return o;
}
}
public class TestJDK {
public static void main(String[] args)throws Exception {
People p = new Employee();
People proxy = (People)new Scalper().getProxy(p);
proxy.buyTicket(1);
byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{p.getClass()});
FileOutputStream os = new FileOutputStream("Proxy0.class");
os.write(bytes);
os.close();
}
}
结果就不贴了!
然后看一下代理类proxy的class文件:
public final class $Proxy0 extends Proxy implements Employee {
private static Method m1;
private static Method m8;
private static Method m2;
private static Method m3;
private static Method m6;
private static Method m5;
private static Method m7;
private static Method m9;
private static Method m0;
private static Method m4;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void notify() throws {
try {
super.h.invoke(this, m8, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
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 void buyTicket(int var1) throws {
try {
super.h.invoke(this, m3, new Object[]{Integer.valueOf(var1)});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void wait(long var1) throws InterruptedException {
try {
super.h.invoke(this, m6, new Object[]{Long.valueOf(var1)});
} catch (RuntimeException | InterruptedException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final void wait(long var1, int var3) throws InterruptedException {
try {
super.h.invoke(this, m5, new Object[]{Long.valueOf(var1), Integer.valueOf(var3)});
} catch (RuntimeException | InterruptedException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw new UndeclaredThrowableException(var6);
}
}
public final Class getClass() throws {
try {
return (Class)super.h.invoke(this, m7, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void notifyAll() throws {
try {
super.h.invoke(this, m9, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void wait() throws InterruptedException {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | InterruptedException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
m8 = Class.forName("com.simon.jdk.Employee").getMethod("notify", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.simon.jdk.Employee").getMethod("buyTicket", new Class[]{Integer.TYPE});
m6 = Class.forName("com.simon.jdk.Employee").getMethod("wait", new Class[]{Long.TYPE});
m5 = Class.forName("com.simon.jdk.Employee").getMethod("wait", new Class[]{Long.TYPE, Integer.TYPE});
m7 = Class.forName("com.simon.jdk.Employee").getMethod("getClass", new Class[0]);
m9 = Class.forName("com.simon.jdk.Employee").getMethod("notifyAll", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m4 = Class.forName("com.simon.jdk.Employee").getMethod("wait", new Class[0]);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
里面有个方法:
public final void buyTicket(int var1) throws {
try {
super.h.invoke(this, m3, new Object[]{Integer.valueOf(var1)});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
super.h.invoke();这里的h是InvocationHandler,而Scalper实现了此接口,重写了这个方法,所以调用的就是Scalper的invoke方法。this就是当前的代理类,m3是Employee类的buyTicket方法,后面的是参数。正好就去调用代理类Scalper的invoke方法。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("获取所有票");
Object o = method.invoke(target, args);
System.out.println("获取符合的票");
return o;
}
Object o = method.invoke(target, args);通过反射,调用target的method方法,target就是我们的Employee,而method就是buyTicket方法。