1. 举例
- 接口
public interface Hello {
void hello(String name);
}
- 实现类
public class HelloImpl implements Hello {
@Override
public void hello(String name) {
System.out.println("Hello, " + name);
}
}
- 代理类:拦截方法,统计执行时间
public class HelloProxy implements InvocationHandler {
private HelloImpl impl;
public HelloProxy(HelloImpl impl) {
this.impl = impl;
}
public Hello create() {
return (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(),
new Class<?>[]{Hello.class}, this);
}
/**
* 方法拦截
* @param proxy 真正的代理类实例
* @param method 拦截的接口方法
* @param args 方法调用参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.nanoTime();
System.out.println("执行" + proxy.getClass().getName() + "." + method.getName());
// 反射调用代理接口实现类方法
Object result = method.invoke(impl, args);
long endTime = System.nanoTime();
System.out.println("耗时" + (endTime - startTime) + "纳秒");
return result;
}
}
- 测试
Hello hello = new HelloProxy(new HelloImpl()).create();
hello.hello("World");
执行结果:
执行com.sun.proxy.$Proxy0.hello
Hello, World
耗时371467纳秒
2. 代理类
- 获取代理类Class文件
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{ Hello.class });
FileOutputStream fos = null;
try {
fos = new FileOutputStream("D:/Temp/$Proxy0.class");
fos.write(classFile);
fos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 生成的代理类
// 继承Proxy,实现接口
public final class $Proxy0 extends Proxy implements Hello {
private static Method objectHashCode;
private static Method objectEquals;
private static Method objectToString;
private static Method proxyHello;
static {
try {
// 获取所有要重载的方法
objectHashCode = Class.forName("java.lang.Object").getMethod("hashCode");
objectEquals = Class.forName("java.lang.Object").getMethod("equals",
Class.forName("java.lang.Object"));
objectToString = Class.forName("java.lang.Object").getMethod("toString");
proxyHello = Class.forName("Hello").getMethod("hello",
Class.forName("java.lang.String"));
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
// 代理构造方法,传入InvocationHandler实例
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
// 重载Object.hashCode()
public final int hashCode() throws {
try {
// 转发到InvocationHandler.invoke
return (Integer)super.h.invoke(this, objectHashCode, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
// 重载Object.equals()
public final boolean equals(Object var1) throws {
try {
// 转发到InvocationHandler.invoke
return (Boolean)super.h.invoke(this, objectEquals, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
// 重载Object.toString()
public final String toString() throws {
try {
// 转发到InvocationHandler.invoke
return (String)super.h.invoke(this, objectToString, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
// 重载接口方法
public final void hello(String var1) throws {
try {
// 转发到InvocationHandler.invoke
super.h.invoke(this, proxyHello, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
}
3. Proxy
Proxy提供静态方法创建动态代理类和实例,亦是所有动态代理类的基类。
为接口Foo创建代理:
InvocationHandler handler = new MyInvocationHandler(...);
Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
或:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class<?>[]{ Foo.class }, handler);
代理类运行时生成,实现代理接口,将所有接口方法的调用转发到InvocationHandler.invoke(Object proxy, Method method, Object[] args)。
invoke()可以通过反射调用代理接口真正实现类的相应方法,并在反射调用前后执行其他操作如计时,以完成拦截目的。
public class Proxy {
// 生成代理类实例
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
// 代理类要实现的接口
final Class<?>[] intfs = interfaces.clone();
// 生成代理类
Class<?> cl = getProxyClass0(loader, intfs);
// 代理类构造方法
Constructor<?> cons = cl.getConstructor(new Class<?>[]{ InvocationHandler.class });
// 生成代理类实例
return cons.newInstance(new Object[]{h});
}
// 代理类包含InvocationHandler实例
protected InvocationHandler h;
// 代理类构造方法调用
protected Proxy(InvocationHandler h) {
this.h = h;
}
// 代理类缓存
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache =
new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
// 通过ProxyClassFactory生成代理类,并放入缓存
return proxyClassCache.get(loader, interfaces);
}
// 代理类工厂:生成代理类字节代码、定义代理类
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
// 代理类类名前缀
private static final String proxyClassNamePrefix = "$Proxy";
// 代理类编号,以生成唯一类名
private static final AtomicLong nextUniqueNumber = new AtomicLong();
/**
* @param loader 代理类加载器
* @param interfaces 代理类要实现的接口
*/
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
// 验证接口
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
// 类加载器解析的接口类名与指定的相同
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(intf + " is not visible from class loader");
}
// 是接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface");
}
// 接口不重复
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName());
}
}
// 代理类所在包
String proxyPkg = null;
// 代理类默认为public final
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
// 如果代理接口有非public,则使代理类与接口同包
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException("non-public interfaces from different packages");
}
}
}
// 代理类所在包默认为com.sun.proxy
if (proxyPkg == null) {
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
long num = nextUniqueNumber.getAndIncrement();
// 代理类完全限定名
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// 生成代理类字节代码(请参看第2节)
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
try {
// 类加载器定义代理类
return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
}
网友评论