Proxy类 提供了静态方法用来创建动态代理类以及其实例,同时它也是通过调用它的方法产生的动态代理类的父类;这里有两点需要说明:1.动态代理类指的是动态代理类对应的Class 实例;2、 动态代理类的父类: 及所有生成的动态代理类都将继承Proxy类并实现指定的接口方法加上toString,equals,hashcode三个方法。
InvocationHandler handler = new MyInvocationHandler(...);
Class> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
这里需要注意的是获取构造函数时需要获取参数为InvocationHandler.class类型的形参构造函数。
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class>[] { Foo.class },handler);
几个概念:
每个代理类有一个关联的InvocationHandler 实例(这个实例成员是在Proxy 类声明的:protected InvocationHandler h)。对代理类调用实现了代理接口的方法时,都会派发到 InvocationHandler 的invoke方法,同时传递三个参数: proxy instance(代理实例),Method(正在被调用的方法),方式形参的数组。调用处理程序根据需要处理编码的方法调用,并且它返回的结果将作为代理实例上的方法调用的结果返回。
一个代理类具有以下特点:
要理解Proxy可以从三个重要属性,两个重要内部类
三个重要属性如下:
private static final Class>[] constructorParams =
{ InvocationHandler.class };
private static final WeakCache[], Class>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
这里需要先弄懂WeakCache的原理与作用
protected InvocationHandler h;
两个重要方法如下:
public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
// 判断Invocation 对象不能为空
Objects.requireNonNull(h);
// 复制代理接口
final Class>[] intfs = interfaces.clone();
// 权限校验主要检查loader是否能够加载代理接口对应的Class 实例
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* 查找代理类的Class 实例
*/
Class> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 通过反射获取代理类的构造函数
final Constructor> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 调用构造函数并返回代理实例
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
private static Class> getProxyClass0(ClassLoader loader,
Class>... interfaces) {
// 判断接口长度
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 从缓存中去,没有的话通过ProxyClassFactory 生成,这里要明白WeakCache的机制
return proxyClassCache.get(loader, interfaces);
}
两个重要内部类:
private static final class KeyFactory
implements BiFunction[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}
private static final class ProxyClassFactory
implements BiFunction[], Class>>
{
// 定义代理类的名称前缀
private static final String proxyClassNamePrefix = "$Proxy";
// 全局的代理类生成序列数字,它和名称前缀一起构成代理类的名称
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class> apply(ClassLoader loader, Class>[] interfaces) {
Map, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class> intf : interfaces) {
Class> interfaceClass = null;
try {
// 加载代理接口,及生成Class 实例
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; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
// 记录非public 代理接口所在包,用来保证生成的代理类在同一个包类,同时也验证所有非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");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
// 组装代理类名称
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
/*
* 生成特殊的代理类,这里也提供了把二进制写成.class文件查看代理类的接口的思路
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
// 根据代理类的二级制数据调用defineClass0这个native方法由虚拟机生成代理类的Class实例
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
描述的再多不如真实看一下:查看代理类方法参加:https://blog.csdn.net/u011244682/article/details/96335660
代理接口如下:
public interface PersonService {
public boolean saveUser(String user);
public String getUserName();
}
由JDK生成的动态代理类如下:
package com.leran;
import com.learn.proxy.PersonService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class proxy01 extends Proxy implements PersonService {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m4;
private static Method m0;
public proxy01(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 boolean saveUser(String var1) throws {
try {
return (Boolean)super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
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 String getUserName() throws {
try {
return (String)super.h.invoke(this, m4, (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("com.learn.proxy.PersonService").getMethod("saveUser", Class.forName("java.lang.String"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m4 = Class.forName("com.learn.proxy.PersonService").getMethod("getUserName");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
通过查看生成的代理类结构就知道为什么需要传递InvocationHandler 对象已经为什么需要重写invoke方法以及AOP 在对invoke方法的处理作用。
WeakCache的使用分析:https://blog.csdn.net/u011244682/article/details/96428467
Class类的作用:https://blog.csdn.net/u011244682/article/details/95996222