小编典典

与Java 1.5中的ServiceLoader相似吗?

java

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

ServiceLoader非常适合(我认为,我还没有使用过),但是我需要在Java 1.5中做到。


阅读 226

收藏
2020-09-26

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

更好的异常处理留给读者练习。同样,可以对方法进行参数化以接受调用者选择的ClassLoader。

2020-09-26