是否类似于 Java 1.5 中的 ServiceLoader?

2022-09-03 12:39:11

如何在运行时在实现已定义接口的类路径中发现类?

ServiceLoader很适合(我想,我还没有用过它),但我需要在Java 1.5中做到这一点。


答案 1

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;
}

更好的异常处理留给读者作为练习。此外,该方法可以参数化以接受调用方选择的类加载器。


答案 2

javax.imageio.spi.ServiceRegistry与以前的 Java 版本等效。它从Java 1.4开始可用。

它看起来不像一个通用的实用程序类,但它是。它甚至比 更强大一些,因为它允许对返回的提供程序的顺序进行一些控制,并直接访问注册表。ServiceLoader

查看 http://docs.oracle.com/javase/7/docs/api/index.html?javax/imageio/spi/ServiceRegistry.html


推荐