簡體   English   中英

我可以讓類加載器動態查找 Java 類嗎?

[英]Can I have a classloader find Java classes dynamically?

我想根據運行時條件動態地 select 類的不同實現。 假設我有一個 class 具有完全限定的 class 名稱 C。 我的運行系統可能有很多class C的定義,每一個都在自己的jar中。 我有一個運行時條件(保存在 ThreadLocal 中),它告訴應該選擇哪個定義。

有人在評論中要求我澄清原始要求,因此我將盡我所能澄清要求。 有多個團隊編寫軟件來為這個系統做出貢獻——就像許多獨立模塊中的 4000 個類一樣。 更重要的是,它們可以隨着時間而改變。 它們目前在單獨的 JVM 中運行,因此類重疊沒有問題。 現在我們正在考慮在同一個 JVM 中運行它們,多個版本同時在同一個 JVM 上運行; 使用哪個特定的實現集由 ThreadLocal 區分。 所以最初的問題是如何讓一個線程一次運行一組實現,另一次運行另一個。

我有一個當前使用 OpenJDK 8 的 tomcat 應用程序。

我相信我可以編寫一個自定義的 ClassLoader 來操作類路徑以根據 ThreadLocal 以不同的方式選擇 C 的定義。 但我擔心結果會被緩存在 JVM 代碼緩存之類的地方。 除非我也可以覆蓋該行為,否則下次需要 class 時,運行時條件可能已更改並且緩存中的版本將是錯誤的。

有什么辦法可以做我需要做的嗎?

好吧,簡單的解決方案是具有 class C 的多個定義,而是具有“C1 類”、“C2 類”等(即它們不重疊並且可以同時加載),然后您的運行時屬性只需選擇合適的那個。 這是最簡單的解決方案,因此請先考慮一下。 但它可能無法滿足您的需求。

如果您確實需要對單個“C 類”進行多個單獨的實現,那么您實際上在談論的是“熱插拔”場景。 幸運的是,Tomcat 和其他工具在長時間熱插拔方面表現良好(有限制)。 您可能已經知道這一點,但是“熱插拔”滿足了編寫“C 類”代碼、將其部署到容器、進行嘗試、意識到它有故障、進行快速代碼編輯並想要運行修改代碼而不重新啟動容器。 熱交換通過基本上覆蓋 JVM 中的新實現來實現這一點。 它只能在一定程度上起作用,因為每次“重新部署”都會污染 JVM 的“類空間”,並且您最終會運行“類空間內存”和/或 JVM 開始變得不穩定。 不過,根據您的需求和容差,熱插拔可能會起作用。

做你想做的事情的干凈方法是將 C 定義為接口,然后你可以加載和使用任何實現接口 C 的 class

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM