编程语言
首页 > 编程语言> > java.util.ServiceLoader未加载我的提供程序类

java.util.ServiceLoader未加载我的提供程序类

作者:互联网

我正在尝试整理一个基于SPI的基本处理程序注册表,该注册表是从HandlerRegistry查找的.当我使用ServiceLoader.load(Handler.class)初始化提供程序,然后迭代列表以延迟加载它们时,我没有看到该类的任何实例.为了使这一过程尽可能简单,我的HandlerRegistry类是:

public class HandlerRegistry 
{
  private static HandlerRegistry registry;

  private ServiceLoader<Handler> handlerLoader;

  private HandlerRegistry()
  {
    handlerLoader = ServiceLoader.load(Handler.class);
  }

  public static synchronized HandlerRegistry getRegistry()
  {
    if (registry == null) {
      registry = new HandlerRegistry();
      registry.init();
    }
    return registry;
  }

  private void init()
  {
System.out.println("HandlerRegistry.init()");
  }

  public Handler lookup(String item)
  {
System.out.println("lookup("+item+")");
    try {
      Iterator<Handler> it = handlerLoader.iterator();
      while (it.hasNext()) {
        Handler handler = it.next();
System.out.println("found handler "+handler);
      }
    }
    catch (ServiceConfigurationError err) {
      err.printStackTrace();
    }
    return null;
  }
}

我有一个com.example.handler.Handler接口(为简单起见,现在为空),以及一个实现该接口的com.example.handler.handlers.DummyHandler类.我在jar中创建了一个名为META-INF / services / com.example.handler.Handler的文件,其中包含单行

com.example.handler.handlers.DummyHandler

根据javadoc.我的单元测试只是调用lookup()方法来验证查找项目的处理程序.当然,最终将需要进行某种检查,以查看这是否是该项目的正确处理程序,但是在这一点上,我什至没有看到注册表中加载了我的DummyHandler类.我在这里做错什么了吗?

谢谢!

解决方法:

答案似乎是对配置方式的敏感性.我一直将我的提供程序名称资源文件(一个名为com.example.handler.Handler)直接放置在顶层项目目录中,即/resources/META-INF/services/com.example.handler.Handler.我已经配置了build.gradle以将文件拉出并放入jar中:

jar { from('resources') { include 'META-INF/services/*.*' } }

当我检查jar文件时,文件就在我期望的位置,所以我认为一切都很好.踢了一下,我碰巧将资源文件夹从src / main下移到了presto!有用.我检查了jar文件,它看起来与以前的方法相同,但是由于某种原因,它可以工作.如果可以确定差异,我将进行进一步更新,但是至少我的测试用例现在可以正常工作.

标签:serviceloader,java
来源: https://codeday.me/bug/20191122/2063668.html