1. 程式人生 > >JDK1.8 動態代理機制及原始碼解析

JDK1.8 動態代理機制及原始碼解析

//代理類 public class Proxy implements java.io.Serializable { private static final long serialVersionUID = -2222568056686623797L; //代理類建構函式的引數型別 private static final Class<?>[] constructorParams = { InvocationHandler.class }; //代理類快取 private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new
WeakCache<>(new KeyFactory(), new ProxyClassFactory()); //此代理例項的呼叫處理程式。 protected InvocationHandler h; private Proxy() { } //代理類建構函式,引數型別:constructorParams所指定 protected Proxy(InvocationHandler h) { Objects.requireNonNull(h); this.h = h; } //獲取目標代理類Class物件,需傳入類載入器loader物件和被代理類實現介面陣列interfaces隨想
@CallerSensitive public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces) throws IllegalArgumentException{ //拷貝介面陣列 final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if
(sm != null) { //校驗代理類的訪問問許可權 checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } //獲取代理類Class物件 return getProxyClass0(loader, intfs); } //校驗代理類的訪問問許可權,這一塊比較底層,我也不明白 private static void checkProxyAccess(Class<?> caller, ClassLoader loader, Class<?>... interfaces){ SecurityManager sm = System.getSecurityManager(); if (sm != null) { //獲取呼叫者類的類載入器 ClassLoader ccl = caller.getClassLoader(); if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } ReflectUtil.checkProxyPackageAccess(ccl, interfaces); } } //獲取代理類的Clas物件 private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } //如果存在給定介面的給定裝入器定義的代理類存在,則只返回快取的副本; //否則,它將通過proxyclassfactory建立代理類 //jdk1.8後收斂到這裡 生成代理類位元組碼過程: ProxyClassFactory中了 return proxyClassCache.get(loader, interfaces); } //用於帶有0個實現介面的代理類的key鍵值 private static final Object key0 = new Object(); /* * Key1 and Key2 are optimized for the common use of dynamic proxies * that implement 1 or 2 interfaces. */ /* * a key used for proxy class with 1 implemented interface */ //用於帶有1個實現介面的代理類的key鍵值 private static final class Key1 extends WeakReference<Class<?>> { private final int hash; Key1(Class<?> intf) { super(intf); this.hash = intf.hashCode(); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { Class<?> intf; return this == obj || obj != null && obj.getClass() == Key1.class && (intf = get()) != null && intf == ((Key1) obj).get(); } } // //用於帶有2個實現介面的代理類的key鍵值 private static final class Key2 extends WeakReference<Class<?>> { private final int hash; //弱引用物件:存放第二個介面類物件 private final WeakReference<Class<?>> ref2; Key2(Class<?> intf1, Class<?> intf2) { super(intf1); hash = 31 * intf1.hashCode() + intf2.hashCode(); ref2 = new WeakReference<Class<?>>(intf2); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { Class<?> intf1, intf2; return this == obj || obj != null && obj.getClass() == Key2.class && (intf1 = get()) != null && intf1 == ((Key2) obj).get() && (intf2 = ref2.get()) != null && intf2 == ((Key2) obj).ref2.get(); } } // 這裡用於帶有>=3個實現介面的代理類的key鍵值(可以當實現任意數目介面的代理的key) private static final class KeyX { //介面陣列物件的hash值 private final int hash; //弱引用物件陣列:存放表示介面的類物件陣列 private final WeakReference<Class<?>>[] refs; @SuppressWarnings("unchecked") KeyX(Class<?>[] interfaces) { hash = Arrays.hashCode(interfaces); //構造一個弱引用物件陣列 refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { refs[i] = new WeakReference<>(interfaces[i]); } } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { return this == obj || obj != null && obj.getClass() == KeyX.class && equals(refs, ((KeyX) obj).refs); } private static boolean equals(WeakReference<Class<?>>[] refs1, WeakReference<Class<?>>[] refs2) { //長度是否相等 if (refs1.length != refs2.length) { return false; } //弱引用物件陣列內介面類是否相同 for (int i = 0; i < refs1.length; i++) { Class<?> intf = refs1[i].get(); if (intf == null || intf != refs2[i].get()) { return false; } } return true; } } //將介面陣列對映到一個最佳鍵的函式,其中表示介面的類物件為弱引用。 private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], 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<ClassLoader, Class<?>[], Class<?>> { //所有代理類名稱的字首 private static final String proxyClassNamePrefix = "$Proxy"; //用於生成唯一代理類名稱的下一個數字 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) { //驗證intf介面類Class物件是否為給定的classloder解析的 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"); } /* * Verify that this interface is not a duplicate. * 驗證此介面不是副本。 */ 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; /* * Record the package of a non-public proxy interface so that the * proxy class will be defined in the same package. Verify that * all non-public proxy interfaces are in the same package. * 記錄一個非公共代理介面的包,以便在同一個包中定義代理類。驗證所有非公共代理介面都在同一個包中。 */ for (Class<?> intf : interfaces) { //獲取修飾符 int flags = intf.getModifiers(); if (!Modifier.isPublic(flags)) { //不是public修飾符 //則定義代理類的修飾符符:final accessFlags = Modifier.FINAL; //獲取介面類名稱,如:com.text.MyInterface String name = intf.getName(); int n = name.lastIndexOf('.'); //獲取包名,如:com.text String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); if (proxyPkg == null) { //獲取包名稱 proxyPkg = pkg; } else if (!pkg.equals(proxyPkg)) { //interfaces含有來自不同包的非公共介面,拋錯 throw new IllegalArgumentException( "non-public interfaces from different packages"); } } } if (proxyPkg == null) { //如果沒有非公開的代理介面,使用com.sun.proxy作為包名稱 proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } //選擇要生成的代理類的名稱。 long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; //真正生成指定的代理類位元組碼的地方 byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { //生成Calss物件 return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the * proxy class generation code) there was some other * invalid aspect of the arguments supplied to the proxy * class creation (such as virtual machine limitations * exceeded). */ throw new IllegalArgumentException(e.toString()); } } } //生成代理類物件 @CallerSensitive public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException { //呼叫處理程式不能為空 Objects.requireNonNull(h); //拷貝介面陣列物件 final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } //查詢或生成指定的代理類。 Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. * 呼叫指定的呼叫處理程式的建構函式 */ try { if (sm != null) { //校驗新代理類的許可權 checkNewProxyPermission(Reflection.getCallerClass(), cl); } //獲取代理類建構函式,引數型別必須為InvocationHandler final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; //建構函式不是public,則設定當前建構函式為訪問許可權 if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } }); } //呼叫建構函式構造代理類例項,入引數為‘呼叫處理程式’的例項,看到這裡應該就明白jdk怎麼實現動態代理的吧! 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 void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { if (ReflectUtil.isNonPublicProxyClass(proxyClass)) { //呼叫者類載入器 ClassLoader ccl = caller.getClassLoader(); //代理類的類載入器 ClassLoader pcl = proxyClass.getClassLoader(); // do permission check if the caller is in a different runtime package // of the proxy class //獲取代理類的包名 int n = proxyClass.getName().lastIndexOf('.'); String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n); //獲取呼叫者包名 n = caller.getName().lastIndexOf('.'); String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n); //類載入不相同或包名不相同,校驗許可權 if (pcl != ccl || !pkg.equals(callerPkg)) { sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg)); } } } } public static boolean isProxyClass(Class<?> cl) { return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl); } @CallerSensitive public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException { //驗證該物件實際上是否為上一個代理例項。 if (!isProxyClass(proxy.getClass())) { throw new IllegalArgumentException("not a proxy instance"); } final Proxy p = (Proxy) proxy; final InvocationHandler ih = p.h; if (System.getSecurityManager() != null) { Class<?> ihClass = ih.getClass(); Class<?> caller = Reflection.getCallerClass(); if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), ihClass.getClassLoader())) { ReflectUtil.checkPackageAccess(ihClass); } } return ih; } private static native Class<?> defineClass0(ClassLoader loader, String name, byte[] b, int off, int len); }