静态代理:
动态代理:
jdk动态代理实现:
public class ProxyDemo implements InvocationHandler
{
private Phone apple;
public ProxyDemo(Phone apple)
{
this.apple = apple;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("begin....");
Object result = method.invoke(apple, args);
System.out.println("end......");
return result;
}
public static void main(String[] args)
{
// 将原先在内存中生成的$Prxoy0对象,打印出来
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Apple apple = new Apple();
Phone phone = (Phone)Proxy.newProxyInstance(Apple.class.getClassLoader(), new Class[]{Phone.class}, new ProxyDemo(apple));
phone.say();
}
}
class Apple implements Phone
{
@Override
public void say()
{
System.out.println("apple say hello!");
}
}
interface Phone
{
void say();
}
$Proxy0
final class $Proxy0 extends Proxy implements Phone {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
}
public final String toString() throws { }
public final void say() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {}
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.enjoylearning.mybatis.Phone").getMethod("say");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
先看一下代理对象的class文件结构:
extends Proxy implements Phone 实现我们传入进去的接口
构造: super(var1); 将我们传递的invocationHandler 传入到父类中
方法: 复写的say方法 super.h.invoke(this, m3, (Object[])null); 调用到父类h的invoke,h就是构造传递的invocationHandler
整体思路:
1、调用 Proxy.newInstance(类加载器,接口,调用处理程序)
参数: classloader,是为了将动态生成的代理类加载到内存中
interfaces 是为了构建代理对象时,让
P
r
o
x
y
0
实
现
该
接
口
,
复
写
方
法
i
n
v
o
c
a
t
i
o
n
H
a
n
d
l
e
r
是
为
了
传
递
给
p
r
o
x
y
父
类
,
后
置
处
理
2
、
获
取
到
Proxy0实现该接口,复写方法 invocationHandler 是为了传递给proxy父类,后置处理 2、获取到
Proxy0实现该接口,复写方法invocationHandler是为了传递给proxy父类,后置处理2、获取到Proxy0的class对象和构造方法
3、constract.newInstance() 生成
4、调用的时候,直接调代理对象的say方法,最终调到了h.invoke()