2010-01-20 55 views
18

我想在Java應用程序中實現動態插件功能。理想情況下:在Java中實現動態插件

  • 該應用程序將定義一個接口Plugin與方法如getCapabilities()
  • 插件將是JAR pluginX.jar,其中包含PluginXImpl類實現Plugin(也可能包括其他一些)。
  • 用戶將pluginX.jar放在一個特殊的目錄中或設置一個指向它的配置參數。用戶不一定必須在其類路徑中包含pluginX.jar
  • 應用程序會找到PluginXImpl(也許通過JAR清單,也許通過反射)並將其添加到註冊表中。
  • 客戶端可以獲得PluginXImpl的實例,例如通過調用getPluginWithCapabilities("X")等方法。用戶不一定必須知道插件的名稱。

我有一種感覺,我應該能夠做到這一點與peaberry,但我不能任何意義的文件。我已經投入了一些時間學習Guice,所以我的首選答案不會是「使用Spring Dynamic Modules」。

有人可以給我一個簡單的想法,如何去做這個使用Guice/peaberry,OSGi,或只是普通的Java?

+0

Peaberry和Spring DM都是OSGi上的圖層。 OSGi似乎做了你想做的事情(概念上),但它會做'OSGi-way',並且不會映射到你的確切過程,所以建議谷歌的一些OSGi教程。 – SteveD 2010-01-20 21:41:19

+1

OSGi看起來比peaberry複雜一百倍。任何鏈接到好的教程? – 2010-01-20 21:48:20

回答

17

這其實是很容易使用普通的Java意味着:

既然你不想讓用戶啓動應用程序之前配置classpath中,我將首先創建一個URLClassLoader的使用URL的數組中的文件你的插件目錄。使用File.listFiles查找所有插件jar,然後使用File.toURI()。toURL()獲取每個文件的URL。您應該將系統類加載器(ClassLoader.getSystemClassLoader())作爲父類傳遞給您的URLClassLoader。

如果插件jar包含META-INF/services中的配置文件,如java.util.ServiceLoader的API文檔中所述,那麼現在可以使用ServiceLoader.load(Plugin.class,myUrlClassLoader)來禁止服務加載器爲你的Plugin接口調用iterator()來獲取所有配置的Plugin實現的實例。

你仍然需要提供你自己的包裝來過濾插件的功能,但是這不應該太麻煩,我想。

+0

您能否詳細解釋一下這個問題? – stacker 2010-01-20 21:45:14

+1

除非你有更詳細的問題,否則不要。 – jarnbjo 2010-01-20 22:11:13

+0

@jarnbjo:完全有效!謝謝!我仍然有興趣看到一個peaberry或OSGi解決方案... – 2010-01-20 23:20:41

0

如果您知道這一點,請道歉,但請查看ClassforName方法。它至少在JDBC中用於通過類名動態加載DBMS特定的驅動程序類運行時。

然後我想枚舉目錄中的所有類/ jar文件並加載其中的每個文件並且爲靜態方法getCapabilities()(或您選擇的任何名稱)定義一個接口以返回其功能/描述並不困難無論使用哪種術語和格式對您的系統都有意義。

+0

@ Bandi-T:我在回覆中添加了上面的一些要求。我不想使用'getPluginInstance(「org.example.PluginXImpl」)''或者必須在classpath中有plugins目錄。 – 2010-01-20 20:59:09

+0

@Chris Conway:那麼我很抱歉,那超出了我的想法,我在Java中並沒有太高級的先進性。 – 2010-01-20 21:09:56

1

如果您想在運行期間替換插件,OSGI會很好。在24/7環境中進行錯誤修復。我和OSGI玩了一段時間,但花了太多時間,因爲這不是一個要求,如果你刪除一個捆綁包,你需要一個計劃。

我的卑微的解決方案是,提供一個帶有插件描述符類類名的屬性文件,並讓服務器調用它們來註冊(包括查詢它們的功能)。

這顯然不是最理想的,但我迫不及待地想閱讀接受的答案。

1

與Guice實現插件的最佳方式是Multibindings。鏈接頁面將詳細介紹如何使用多重綁定來託管插件。

+1

「請注意,在系統運行時,此機制無法加載或卸載插件。」在我看來,多重綁定需要插件JAR位於類路徑中,並且用戶需要在配置文件中指定模塊類。也許你可以使用ClassLoader動態加載插件目錄中的JAR,但是你必須使用類似於Service加載器的東西來自動查找模塊。 – 2010-01-21 14:05:14