十一、JAVA多執行緒:執行緒上線文載入器
執行緒上下文類載入器(context class loader)是從 JDK 1.2 開始引入的。類 java.lang.Thread
中的方法 getContextClassLoader()
和 setContextClassLoader(ClassLoader cl)
用來獲取和設定執行緒的上下文類載入器。如果沒有通過 setContextClassLoader(ClassLoader cl)
方法進行設定的話,執行緒將繼承其父執行緒的上下文類載入器。Java 應用執行的初始執行緒的上下文類載入器是系統類載入器。線上程中執行的程式碼可以通過此類載入器來載入類和資源。
前面提到的類載入器的代理模式並不能解決 Java 應用開發中會遇到的類載入器的全部問題。Java 提供了很多服務提供者介面(Service Provider Interface,SPI),允許第三方為這些介面提供實現。常見的 SPI 有 JDBC、JCE、JNDI、JAXP 和 JBI 等。這些 SPI 的介面由 Java 核心庫來提供,如 JAXP 的 SPI 介面定義包含在 javax.xml.parsers
包中。這些 SPI 的實現程式碼很可能是作為 Java 應用所依賴的 jar 包被包含進來,可以通過類路徑(CLASSPATH)來找到,如實現了 JAXP SPI 的 javax.xml.parsers.DocumentBuilderFactory
類中的 newInstance()
方法用來生成一個新的 DocumentBuilderFactory
的例項。這裡的例項的真正的類是繼承自 javax.xml.parsers.DocumentBuilderFactory
,由 SPI 的實現所提供的。如在 Apache Xerces 中,實現的類是 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
執行緒上下文類載入器正好解決了這個問題。如果不做任何的設定,Java 應用的執行緒的上下文類載入器預設就是系統上下文類載入器。在 SPI 介面的程式碼中使用執行緒上下文類載入器,就可以成功的載入到 SPI 實現的類。執行緒上下文類載入器在很多 SPI 的實現中都會用到。
下面介紹另外一種載入類的方法:Class.forName
。
Class.forName
Class.forName
是一個靜態方法,同樣可以用來載入類。該方法有兩種形式:Class.forName(String name, boolean initialize, ClassLoader loader)
和 Class.forName(String className)
。第一種形式的引數 name
表示的是類的全名;initialize
表示是否初始化類;loader
表示載入時使用的類載入器。第二種形式則相當於設定了引數 initialize
的值為 true
,loader
的值為當前類的類載入器。Class.forName
的一個很常見的用法是在載入資料庫驅動的時候。如 Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance()
用來載入 Apache Derby 資料庫的驅動。
推薦閱讀文章:
https://blog.csdn.net/zhoudaxia/article/details/35897057
https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html