查了一些資料也不是太明白兩個的區別,可是前者是最安全的用法html
1
2
3
4
5
6
7
8
9
10
11
|
public
class
Test {
public
static
void
main(String[] args) {
// 此時三個ClassLoader是同一個對象
System.out.println(Thread.currentThread().getContextClassLoader());
// 當前線程的類加載器
System.out.println(Test.
class
.getClassLoader());
// 當前類的類加載器
System.out.println(ClassLoader.getSystemClassLoader());
// 系統初始的類加載器
}
}
|
若是樓主瞭解過openfire應該對ClassLoader有比較深的理解。
打個簡單的比方,你一個WEB程序,發佈到Tomcat裏面運行。
首先是執行Tomcat org.apache.catalina.startup.Bootstrap類,這時候的類加載器是ClassLoader.getSystemClassLoader()。
而咱們後面的WEB程序,裏面的jar、resources都是由Tomcat內部來加載的,因此你在代碼中動態加載jar、資源文件的時候,首先應該是使用Thread.currentThread().getContextClassLoader()。若是你使用Test.class.getClassLoader(),可能會致使和當前線程所運行的類加載器不一致(由於Java天生的多線程)。
Test.class.getClassLoader()通常用在getResource,由於你想要獲取某個資源文件的時候,這個資源文件的位置是相對固定的。java
java的類加載機制(jvm規範)是委託模型,簡單的說,若是一個類加載器想要加載一個類,首先它會委託給它的parent去加載,若是它的全部parent都沒有成功的加載那麼它纔會本身親自來,有點兒像兒子使喚老子的感受。。jvm也拼爹啊,,,,,
在jvm中默認有三類loaer,bootstrap,ext,app,其中boot最大是爺爺,app最小是孫子,ext中間是爹。
它們有權限訪問的classpath也不同,boot是jdk或jre下面的lib目錄,ext是jdk或jre的ext目錄,而app是由用戶指定的路徑,好比用-cp參數指定的目錄或jar。他們沒有權力訪問其餘人的classpath,這樣問題就來鳥,,,,可能有人會問狗司令大人閒得蛋疼啊,搞這麼複雜,聽說是爲了安全考慮,避免用戶的噁心意代碼侵蝕jvm,,問題就是當bootstrap或ext想要加載用戶指定classpath中的類就會失敗,由於這倆貨沒有權限訪問團app路徑中的類的,,因此就搞了這麼一個不三不四的contextloader。。。。apache