回答
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. 与Ext.ux.Livegrid类似吗?
- 3. Ada中的自我引用与Java“this”类似吗?
- 4. 与Python中的SimpleXML类似吗?
- 5. servlet与.Net中的httpHandler类似吗?
- 6. 与LPC1769/FreeRTOS中的shiftOut类似吗?
- 7. 与onPostExecute for InServiceService类似吗?
- 8. erlang:与name_for_pid()类似吗?
- 9. API与GLUTesselator类似吗?
- 10. 控件与Datagrid类似吗?
- 11. Python与UnityScript(JavaScript)类似吗?
- 12. GWT的类与AWT Desktop类似吗?
- 13. 在java中与fork()类似的功能
- 14. Android中的ServiceLoader“无法实例化类”
- 15. 在Android版iOS中与SDWebImage类似吗?
- 16. 在Java 1.5中打印,速度慢吗?
- 17. Splashpage与Swift类似的Twitter吗?
- 18. 与PostgreSQL的MySQL代理类似吗?
- 19. 与Android上的MFMessageComposeViewController类似吗?
- 20. 与powershell相当的Java(或类似的)
- 21. Java中的字符串池的行为与LRU缓存类似吗?
- 22. 嵌入的GlassFish:java.lang.NoClassDefFoundError:JAVA/UTIL /的ServiceLoader
- 23. Zend页面缓存与smarty类似吗?
- 24. Qt框架与Titanium类似吗?
- 25. Javascript auth与Python auth类似吗?
- 26. 多平台MBaas与CloudKit类似吗?
- 27. Rails弹簧配置与Zeus类似吗?
- 28. 在Eclipse Plugins中测试ServiceLoader
- 29. 1.5 JVM上的Java 1.4类性能
- 30. Java与实例或字符串类似