含義
1.雙親委派模型是從JDK1.2開始至今都在沿用的類加載模型,具體的邏輯是:
先看源碼:
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;
}
}
註釋已經很清晰了:
首先,根據類的全限定名通過findLoadedClass方法查詢該類是否已被加載,如果已經被加載過了則判斷resolve的值,該值是標識類是否link了,(This (misleadingly named) method may be
used by a class loader to link a class.)默認傳false,也就是說直接返回了該類.重點是如果該類沒有加載過:再判斷是否有父類加載器(通過組合的方式持有),如果有父類加載器,就用父類加載器加載,如果沒有說明其上層只剩啓動類加載器了,就用啓動類加載器加載,(因爲啓動類加載器是通過c++寫的).
如果其父類加載器或者啓動類加載器都不能加載,會拋出異常,然後由本類加載器的findClass方法進行加載,然後記錄類加載器的的狀態信息
優點
優點也就是使用該模型的必要性:這種加載機制可以使類連同其加載器有了一種具有優先級的層次關係,保證了同一個類的全限定名只對應一個類,保證了其唯一性,否者,根本就沒法保證java的工作機制.
缺點
顯而易見,如果上層的類加載器在工作的時候需要下層的類加載器進行加載操作則是不支持的,但這種場景有很多的場景,比如,JNDI,JDBC,JBI等涉及到SPI(接口提供者)
的地方,都是爲了解決這個問題而提出的方式,具體可以看下篇 破壞雙親委派模型.這裏不做細緻的記錄.