1. 程式人生 > >Java執行緒上下文類載入器與SPI

Java執行緒上下文類載入器與SPI

執行緒上下文類載入器(context class loader)是從JDK 1.2開始引入的。類 java.lang.Thread中的方法getContextClassLoader()和setContextClassLoader(ClassLoader cl)用來獲取和設定執行緒的上下文類載入器。如果沒有通過 setContextClassLoader(ClassLoader cl)方法進行設定的話,執行緒將繼承其父執行緒的上下文類載入器。Java 應用執行的初始執行緒的上下文類載入器是系統類載入器。線上程中執行的程式碼可以通過此類載入器來載入類和資源。 為了載入類,Java還提供了很多服務提供者介面(Service Provider Interface,SPI),允許第三方為這些介面提供實現。那類載入就會存在問題:SPI 的介面是 Java 核心庫的一部分,是由引導類載入器來載入的;SPI 實現的 Java 類一般是由系統類載入器來載入的。引導類載入器是無法找到 SPI 的實現類的,因為它只加載 Java 的核心庫。在 SPI 介面的程式碼中使用執行緒上下文類載入器,就可以成功的載入到 SPI 實現的類。java的雙親委託類載入機制(ClassLoader A -> System class loader -> Extension class loader -> Bootstrap class loader)可以保證核心類的正常安全載入。但是右邊的 Bootstrap class loader 所載入的程式碼需要反過來去找委派鏈靠左邊的 ClassLoader A 去載入東西的時候,就需要委派鏈左邊的 ClassLoader 設定為執行緒的上下文載入器即可。

我們拿jdbc為例子分析:

檢視DriverManager原始碼

private DriverManager(){}

/**
* Load the initial JDBC drivers by checking the System property
* jdbc.properties and then use the {@code ServiceLoader} mechanism
*/
static {
  loadInitialDrivers();
  println("JDBC DriverManager initialized");
}

private static void loadInitialDrivers() {
      AccessController.doPrivileged(new PrivilegedAction<Void>() {
  //省略...
  public Void run() {
  ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
  Iterator driversIterator = loadedDrivers.iterator();
  //省略...
  return null;
  }
  });
 }

}
其中ServiceLoader.load(Driver.class)方法原始碼:
public static <S> ServiceLoader<S> load(Class<S> service) {
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    return ServiceLoader.load(service, cl);
}

可見jdbc在通過SPI方式載入service實現類的時候是使用的執行緒上下文載入器載入的。

相關推薦

Java執行上下文載入SPI

執行緒上下文類載入器(context class loader)是從JDK 1.2開始引入的。類 java.lang.Thread中的方法getContextClassLoader()和setContextClassLoader(ClassLoader cl)用來獲取和設定

05執行上下文載入

在JDK1.2後,可以使用getContextClassLoader()和setContextClassLoader()來獲取和設定當前執行緒的上下文類載入器,如果沒有設定,預設與父執行緒一致。 Java 提供了很多服務提供者介面(Service Provider Inte

真正理解執行上下文載入(多案例分析)

前言 此前我對執行緒上下文類載入器(ThreadContextClassLoader,下文使用TCCL表示)的理解僅僅侷限於下面這段話: Java 提供了很多服務提供者介面(Service Provider Interface,SPI),允許第

執行上下文載入(Context ClassLoader)

1.執行緒上下文類載入器是從jdk1.2開始引入的,類Thread中的getContextClassLoader()與setContextClassLoader(ClassLoader c1),分別用來獲取和設定類載入器如果沒有通過setContextClassLoader方

雙親委派模型和執行上下文載入

最近在讀《架構探險-從零開始寫java web框架》一書時,看到了一個獲取類載入器的地方是這樣寫的: public static ClassLoader getClassLoad

深入載入----執行上下文載入

            深入類載入器(四)----執行緒上下文切換類載入器                       執行緒上下文類載入器 我們知道在java中的載入器的載入模式是雙親委託模式,

載入 - 自定義系統載入執行上下文載入

自定義系統類載入器 ClassLoader.getSystemClassLoader()方法詳解 方法說明 返回用於委託的系統類載入器,它是新建ClassLoader例項的預設的委託雙親,通常也是啟動應用的類載入器。 這個方法在執行啟動期間很早的時候就被呼叫,在呼叫時首先會建立系統載入器,而且會將其設定為呼

執行上下文載入ContextClassLoader記憶體洩漏隱患

前提 今天(2020-01-18)在編寫Netty相關程式碼的時候,從Netty原始碼中的ThreadDeathWatcher和GlobalEventExecutor追溯到兩個和執行緒上下文類載入器ContextClassLoader記憶體洩漏相關的Issue: ThreadDeathWatcher cau

可怕的執行上下文裝載(TCCL)

在明天的 OSGi 2012 社群活動上,我將以“如何使你的類庫在不依賴 OSGi 的情況下進行友好地 OSGi”為主題進行演講。在演講中我將會提及 Java 的執行緒上下文類載入器(TCCL),但是整個演講只有 25 分鐘,我沒有更多時間對此進行深入討論。所以我寫這篇部落格

Java自定義載入雙親委派模型[轉]

其實,雙親委派模型並不複雜。自定義類載入器也不難!隨便從網上搜一下就能搜出一大把結果,然後copy一下就能用。但是,如果每次想自定義類載入器就必須搜一遍別人的文章,然後複製,這樣顯然不行。可是自定義類載入器又不經常用,時間久了容易忘記。相信你經常會記不太清loa

Java載入雙親委派模型

1. 什麼是類載入機制? 程式碼編譯的結果從本地機器碼轉變成位元組碼,是儲存格式的一小步,卻是程式語言發展的一大步。 Java虛擬機器把描述類的資料從Class檔案載入進記憶體,並對資料進行校驗,轉換解析和初始化,最終形成可以唄虛擬機器直接使用的Java型別,這就是虛擬

十一、JAVA執行執行上線文載入

       執行緒上下文類載入器(context class loader)是從 JDK 1.2 開始引入的。類 java.lang.Thread中的方法 getContextClassLoader()和 setContextC

Java載入反射

一個命令對應一個程序 當我們啟動一個Java程式,即啟動一個main方法時,都將啟動一個Java虛擬機器程序,不管這個程序有多麼複雜。而不同的JVM程序之間是不會相互影響的。這也就是為什麼說,Java程式只有一個入口——main方法,讓虛擬機器呼叫。而兩個m

Java 執行(Thread)技術深入理解

Thread基礎部分 在各種程式語言中都有thread(執行緒)技術,執行緒保證在一個main中(主執行緒)可以同時進行兩個或多個不同的事件,通俗點說就是你在上廁所的同時還可以玩手機,是吧!美滋滋。而Thread就相當於提供了同時做兩件事的條件和環境。接下來在深入一點理解計算機中的Threa

java載入以及spi

類載入器概述: 每個編寫的”.java”拓展名類檔案都儲存著需要執行的程式邏輯,這些”.java”檔案經過Java編譯器編譯成拓展名為”.class”的檔案,”.class”檔案中儲存著Java程式碼經轉換後的虛擬機器指令,當需要使用某個類時,虛擬機器將會載入它的”.class”檔案,並

Java執行安全

執行緒不安全的類: HashMap LinkedHashMap TreeMap ArrayList LinkedList HashSet TreeSet LinkedHashSet StringBuilder 執行緒安全的類: ConcurrentHashMap Hasht

Java高新技術第一篇 載入詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

JVM載入雙親委派模型(二)

(7)URLClassLoader類 前面說到,ClassLoader這個頂級父類只是定義好了雙親委派模型的工作機制;但是ClassLoader是個抽象類,無法直接建立物件,所以需要由繼承它的子類完成建立物件的任務。子類需要自己實現findClass方法,並且在例項化時指定parent屬性的值

JVM載入雙親委派模型(一)

(1)動態載入       類載入器是 Java 語言的一個創新,也是 Java 語言流行的重要原因之一。它使得 Java 類可以被動態載入到 Java 虛擬機器中並執行。類載入器從 JDK 1.0 就出現了,最初是為了滿足 Java Applet 的需要

Java 執行工具

1. CountDownLatch CountDownLatch首先定義任務次數,並呼叫await()方法等待任務完成。呼叫countDown()方法表明已經完成一項任務,當任務全部完成後,繼續await()方法後的任務。 public class CountDownLatchT