- .测试程序:先新建一个要被代理的对象和一个事务处理器的对象,将要被代理的对象car传进事务处理器的构造函数中,最后用proxy生成一个代理对象,最后调用要使用的方法。
/**
* JDK动态代理测试类
*/
public static void main(String[] args) {
Car car = new Car();
InvocationHandler h = new TimeHandler(car);
Class<?> cls = car.getClass();
/**
* loader 类加载器
* interfaces 实现接口
* h InvocationHandler
*/
Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), h);
m.move();
}
- 事务处理器(InvocationHandler):事物处理器的作用就是扩展被代理对象的方法的功能,根据传进来的代理对象通过反射机制,获取被代理对象的方法,在调用被代理对象之前或者之后加入一些自己的逻辑,达到扩展功能或者权限控制。
-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
方法参数:proxy代表要被代理的对象,method要被代理的方法,args方法参数。
- Proxy用来生成代理对象:返回的是&Proxy0的一个对象,并不是被代理的一个对象
-
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
方法参数:loader(类加载器),interfaces(被代理对象的类实现的接口),h(事务处理器)
Car car = new Car();
InvocationHandler h = new TimeHandler(car);
Class<?> cls = car.getClass();
Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
System.out.println("m的类类型:" + m.getClass());
Class<?>[] interfaces = m.getClass().getInterfaces();
System.out.print("实现的接口:");
Class[] var6 = interfaces;
int var7 = interfaces.length;
int var8;
for(var8 = 0; var8 < var7; ++var8) {
Class<?> i = var6[var8];
System.out.print(i.getName() + " ");
}
System.out.println();
Field[] fields = m.getClass().getDeclaredFields();
System.out.print("m的属性有:");
Field[] var13 = fields;
var8 = fields.length;
int var16;
for(var16 = 0; var16 < var8; ++var16) {
Field f = var13[var16];
System.out.print(f.getName() + " ");
}
System.out.println();
System.out.print("Proxy的方法有:");
Method[] methods = m.getClass().getMethods();
Method[] var15 = methods;
var16 = methods.length;
for(int var17 = 0; var17 < var16; ++var17) {
Method mt = var15[var17];
System.out.print(mt.getName() + " ");
}
System.out.println();
m.move();
m的类类型:class com.sun.proxy.$Proxy0
实现的接口:Moveable
m的属性有:m1 m3 m2 m0
Proxy的方法有:equals toString hashCode move isProxyClass newProxyInstance getInvocationHandler getProxyClass wait wait wait getClass notify notifyAll
开始前
跑起来
结束了,时间为:775毫秒
通过输出的结果可以知道,m并不是被代理对象的一个实例,他是$Proxy的一个实例,实现了Moveable接口,并且从写了object的方法,实现了Maveable接口中方法move。通过反编译,我们再看一下$Proxy的源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.sun.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements Moveable {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
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});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void move() 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("Moveable").getMethod("move");
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());
}
}
}
发现$Proxy类继承了Proxy类,并在在move方法中调用了事务处理器中的invoke方法。