public class ProxySubject implements InvocationHandler {
private Object target;
/**
* @param obj
* 真實對象
* @return 代理對象
*/
public Object bind(Object obj) {
this.target = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
/*
* 返回調用實例方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target);
}
}
動態代理實現原理
//動態代理類的參數類型
private static final Class<?>[] constructorParams ={ InvocationHandler.class };
protected InvocationHandler h;
//構造方法私有化,不允許外部實例化對象,單例設計
private Proxy() {
}
//有參的也被被封裝起來,用protecct貌似是爲了方便吧子類調用
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
//提供統一的獲取代理類的實例方法(摘要主要的方法,其他省略)
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException {
//類似有getClass,Class.forName()的一個獲取Class對象的方法
Class<?> cl = getProxyClass0(loader, intfs);
//反射獲得構造
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//代理類返回實例化對象
return cons.newInstance(new Object[]{h});
}
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
//它將通過proxyclassfactory創建代理類
// 給定的接口存在,從緩存中獲取
return proxyClassCache.get(loader, interfaces);
}
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
KeyFactory獲得類加載器和接口
ProxyClassFactory 獲得真正的代理類
//這是代理類工廠類
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
//定義的名字前綴
private static final String proxyClassNamePrefix = "$Proxy";
// 生成的數,跟在$Proxy這個名字之後,JDK動態代理類的名字都是 $ProxyN (N=0,1,2,3,4,5,6,7,8)
private static final AtomicLong nextUniqueNumber = new AtomicLong();
//驗證類加載器是否解析過這個接口
@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");
}
//判斷Class對象是否代表的是一個接口
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;
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;
//產生本地字節文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//按照產生的字節碼文件來產生動態代理類
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
public static byte[] generateProxyClass(final String name,
Class[] interfaces)
{
ProxyGenerator gen = new ProxyGenerator(name, interfaces);
// 這裏動態生成代理類的字節碼,比較複雜
final byte[] classFile = gen.generateClassFile();
// 把所生成的代理類的字節碼保存到硬盤上
if (saveGeneratedFiles) {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
try {
FileOutputStream file =
new FileOutputStream(dotToSlash(name) + ".class");
file.write(classFile);
file.close();
return null;
} catch (IOException e) {
throw new InternalError(
"I/O exception saving generated file: " + e);
}
}
});
}
// 返回代理類的字節碼
return classFile;
}
JNI調用原生態方法
private static native Class<?> defineClass0(ClassLoader loader, String name,byte[] b, int off, int len);