代理
Java SDK代理
Java SDK 是一种基于对象的代理
Java SDK 是一种面向接口的代理
Java 代码实现
接口定义
public interface Transfer {
void speed();
}
子类实现
public class Car implements Transfer {
private String name;
private String type;
public String getName() {
return name;
}
public String getType() {
return type;
}
@Override
public String toString() {
return "Car{" + "name='" + name + '\'' + ", type='" + type + '\'' + '}';
}
/**
* 继承父类方法
*/
@Override
public void speed() {
System.out.println("car, so fast");
}
/**
* 子类方法
*/
public void form() {
System.out.println("三厢");
}
}
InvocationHandler 实现
public class MyInvocationHandler implements InvocationHandler {
private Object **target**;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object object = null;
System.out.println("invoke before ....");
object= method.invoke(target,args);
System.out.println("invoke after ...");
return object;
}
}
调用生效
import sun.misc.ProxyGenerator;
import java.lang.reflect.Proxy;
public class JavaSDKProxyDemo {
public static void main(String[] args) {
Car car = new Car();
Transfer proxy = (Transfer) Proxy.newProxyInstance(Transfer.class.getClassLoader(), new Class[]{Transfer.class}, new MyInvocationHandler(car));
proxy.speed();
//生成代理类 -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true (保存代理类信息)
//ProxyGenerator.generateProxyClass("$MyTransferProxy", new Class[]{Transfer.class});
}
}
执行结果
invoke before ....
car, so fast
invoke after ...
从生成的代理类看Java SDK 动态代理的运行机制
$MyTransferProxy类定义
public final class $MyTransferProxy extends Proxy implements Transfer {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $MyTransferProxy(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 void speed() throws {
try {
super.h.invoke(this, m3, (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 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"));
m3 = Class.forName("代理.javaSDK代理.Transfer").getMethod("speed");
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());
}
}
}
- $MyTransferProxy 构造方法会将 InvocationHandler 传递给Super类,也就是Proxy类
- 代理方法 speed() 的调用会委托给super类中的 InvocationHandler对象的invoke方法执行,也正是我们自定义的MyInvocationHandler的invoke方法
类图
从代理类源码和类图可以看到:
1、Java SDK动态代理是基于接口实现:目标类、代理类都实现同一接口;
2、动态生成的代理类继承Proxy类,持有InvocationHandler具体实现类对象;
3、InvocationHandler具体实现类将Car类作为成员变量
调用逻辑就变得清晰明了:
//调用代理类的方法,转而调用Proxy类中持有InvocationHandler对象(也就是我们自己实现的MyInvocationHandler的invoke方法)
super.h.invoke(this, m3, (Object[])null);
问题
Proxy类在生成代理类的时候,为什么要显式穿ClassLoader?
Transfer proxy = (Transfer) Proxy.newProxyInstance(Transfer.class.getClassLoader(), new Class[]{Transfer.class}, new MyInvocationHandler(car));