回答
Java 1.5中沒有內置任何內容。我自己實現了它;它不是太複雜。但是,當我們升級到Java 6時,我將不得不使用調用ServiceLoader
來替換對我的實現的調用。我本可以在應用程序和加載器之間定義一個小橋樑,但我只在幾個地方使用它,而封裝器本身就是ServiceLoader的一個很好的候選者。
這是核心思想是:
public <S> Iterable<S> load(Class<S> ifc) throws Exception {
ClassLoader ldr = Thread.currentThread().getContextClassLoader();
Enumeration<URL> e = ldr.getResources("META-INF/services/" + ifc.getName());
Collection<S> services = new ArrayList<S>();
while (e.hasMoreElements()) {
URL url = e.nextElement();
InputStream is = url.openStream();
try {
BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while (true) {
String line = r.readLine();
if (line == null)
break;
int comment = line.indexOf('#');
if (comment >= 0)
line = line.substring(0, comment);
String name = line.trim();
if (name.length() == 0)
continue;
Class<?> clz = Class.forName(name, true, ldr);
Class<? extends S> impl = clz.asSubclass(ifc);
Constructor<? extends S> ctor = impl.getConstructor();
S svc = ctor.newInstance();
services.add(svc);
}
}
finally {
is.close();
}
}
return services;
}
更好的異常處理是作爲練習留給讀者。另外,該方法可以被參數化爲接受調用者選擇的ClassLoader。
沒有可靠的方法來知道類路徑中的類是什麼。根據其documentation,ServiceLoader依靠外部文件來告訴它要加載哪些類;你可能想要做同樣的事情。基本的想法是用一個文件加載類的名字,然後用反射來實例化它/它們。
ServiceLoader是相當基本的,自1.3版以來一直在JDK中使用(非正式)。 ServiceLoader終於使它成爲一流的公民。它只是尋找一個爲你的接口命名的資源文件,它基本上捆綁在庫jar的META-INF目錄中。
該文件包含要加載的類的名稱。
所以,你有一個名爲文件:
META-INF /服務/ com.example.your.interface
和裏面是一個單行:com.you.your.interfaceImpl 。
代替ServiceLoader,我喜歡Netbeans Lookup。它適用於1.5(也許1.4)。
開箱即用,它與ServiceLoader完全相同,使用起來也很簡單。但它提供了更多的靈活性。
這裏有一個鏈接:http://openide.netbeans.org/lookup/
這裏有一個大約的ServiceLoader的文章,但它提到的Netbeans查找在底部: http://weblogs.java.net/blog/timboudreau/archive/2008/08/simple_dependen.html
你有沒有想過使用OSGi框架的?
javax.imageio.spi.ServiceRegistry
等同於以前的Java版本。它自Java 1.4起可用。
它看起來不像一般的工具類,但它是。它比ServiceLoader
更強大,因爲它允許對返回提供程序的順序進行一些控制,並直接訪問註冊表。
見http://docs.oracle.com/javase/7/docs/api/index.html?javax/imageio/spi/ServiceRegistry.html
不幸的是,
沒有什麼內置的Java 1.5此...
是唯一的真理的一部分。
周圍有非標準sun.misc.Service
。
http://www.docjar.com/docs/api/sun/misc/Service.html
當心,這不是標準的J2SE API的一部分! 這是Sun JDK的非標準部分。 所以,如果你使用JRockit
,那麼你不能依賴它。
這是一個老問題,但另一種選擇是使用包級別註釋。 查看我的聯繫方式:Find Java classes implementing an interface
軟件包級別註釋是package-info.java類中的註釋。
JAXB使用此代替服務加載器。我也認爲它比服務加載器更靈活。
- 1. JAVA 6 ServiceLoader
- 2. Java Applet和ServiceLoader
- 3. 與Ext.ux.Livegrid類似嗎?
- 4. ArrayList的ArrayList與Java中的2D數組類似嗎?
- 5. Ada中的自我引用與Java「this」類似嗎?
- 6. 與Python中的SimpleXML類似嗎?
- 7. python中的循環與matlab類似嗎?
- 8. servlet與.Net中的httpHandler類似嗎?
- 9. 與LPC1769/FreeRTOS中的shiftOut類似嗎?
- 10. 與SqlSoup for Scala類似嗎?
- 11. JSON parseString與parseInt類似嗎?
- 12. 控件與Datagrid類似嗎?
- 13. erlang:與name_for_pid()類似嗎?
- 14. 與onPostExecute for InServiceService類似嗎?
- 15. Python與UnityScript(JavaScript)類似嗎?
- 16. API與GLUTesselator類似嗎?
- 17. Android中的ServiceLoader「無法實例化類」
- 18. GWT的類與AWT Desktop類似嗎?
- 19. 在java中與fork()類似的功能
- 20. 在Android版iOS中與SDWebImage類似嗎?
- 21. groovy與java類似的數據類型?
- 22. 如何將Java 1.5類與Java 1.6類連接起來?
- 23. Java中的類似「Handler」類
- 24. 如何創建從WSDL的Java類(皁1.2)與Java的JDK-1.5
- 25. 在Java 1.5中打印,速度慢嗎?
- 26. 準備好的語句JDBC JAVA請求與PHP類似嗎?
- 27. 與Android上的MFMessageComposeViewController類似嗎?
- 28. 與PostgreSQL的MySQL代理類似嗎?
- 29. Splashpage與Swift類似的Twitter嗎?
- 30. 與powershell相當的Java(或類似的)