https://blog.csdn.net/zhangliangzi/article/details/51338291 -參考html
雙親委派過程:當一個類加載器收到類加載任務時,當即將任務委派給它的父類加載器去執行,直至委派給最頂層的啓動類加載器爲止。若是父類加載器沒法加載委派給它的類時,將類加載任務退回給它的下一級加載器去執行;除了啓動類加載器之外,每一個類加載器擁有一個父類加載器,用戶的自定義類加載器的父類加載器是AppClassLoader;雙親委派模型能夠保證全限名指定的類,只被加載一次;雙親委派模型不具備強制性約束,是Java設計者推薦的類加載器實現方式;java
雙親委派模型的源碼實現:api
主要體如今ClassLoader的loadClass()方法中,思路很簡單:先檢查是否已經被加載過,若沒有加載則調用父類加載器的loadClass()方法,若父類加載器爲空則默認使用啓動類加載器做爲父類加載器。若是父類加載器加載失敗,拋出ClassNotFoundException異常後,調用本身的findClass()方法進行加載。tomcat
/** * Loads the class with the specified <a href="#name">binary name</a>. The * default implementation of this method searches for classes in the * following order: * * <ol> * * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class * has already been loaded. </p></li> * * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method * on the parent class loader. If the parent is <tt>null</tt> the class * loader built-in to the virtual machine is used, instead. </p></li> * * <li><p> Invoke the {@link #findClass(String)} method to find the * class. </p></li> * * </ol> * * <p> If the class was found using the above steps, and the * <tt>resolve</tt> flag is true, this method will then invoke the {@link * #resolveClass(Class)} method on the resulting <tt>Class</tt> object. * * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link * #findClass(String)}, rather than this method. </p> * * <p> Unless overridden, this method synchronizes on the result of * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method * during the entire class loading process. * * @param name * The <a href="#name">binary name</a> of the class * * @param resolve * If <tt>true</tt> then resolve the class * * @return The resulting <tt>Class</tt> object * * @throws ClassNotFoundException * If the class could not be found */ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
雙親委派的好處: less
使用雙親委派模型來組織類加載器之間的關係,有一個很明顯的好處,就是Java類隨着它的類加載器(說白了,就是它所在的目錄)一塊兒具有了一種帶有優先級的層次關係,這對於保證Java程序的穩定運做很重要。例如,類java.lang.Object類存放在JDK\jre\lib下的rt.jar之中,所以不管是哪一個類加載器要加載此類,最終都會委派給啓動類加載器進行加載,這邊保證了Object類在程序中的各類類加載器中都是同一個類。ide
破壞雙親委派的模型: ui
參考:this
[1] 《Java虛擬機精講》[2] 《深刻理解Java虛擬機 JVM高級特性與最佳實踐》[3] http://blog.csdn.net/zhangliangzi/article/details/51338291spa
[2] tomcat類加載器.net
[3] 深刻探討 Java 類加載器:https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
[4] 深刻理解 Tomcat(四)Tomcat 類加載器之爲什麼違背雙親委派模型 http://www.javashuo.com/article/p-nqgssvfe-d.html