当前位置: 首页 > 面试题库 >

如何在Java中实现API / SPI模式?

柯天宇
2023-03-14
问题内容

我正在创建一个框架,该框架公开了供开发人员使用的API:

public interface MyAPI {
    public void doSomeStuff();

    public int getWidgets(boolean hasRun);
}

开发人员应该做的就是针对这些API方法编写项目代码。我还希望它们能够在运行时类路径上放置不同的“驱动程序” /“
API绑定”(与JDBC或SLF4J的工作方式相同),并使API方法调用(doSomeStuff()等)在不同的第三方资源(文件)上运行,服务器等)。因此,相同的代码和API调用将映射到操作上的不同资源,这取决于驱动器/绑定运行时类路径看(即myapi- ftpmyapi-sshmyapi-teleportation)。

我怎样写(和封装)的SPI允许这样的运行时绑定, 再映射MyAPI调用正确的(混凝土)执行?换句话说,如果myapi- ftp允许您getWidgets(boolean)从FTP服务器访问,该如何处理(以同时使用API​​和SPI)?

具体的,有效的Java代码示例的加分项!提前致谢!


问题答案:

看一看java.util.ServiceLoader类。

通常,这个想法是这样的:

API罐

  • 提供接口
  • 使用ServiceLoader类查找实现

绑定/驱动程序罐

  • 实施界面
  • 创建文件META-INF /并指定实现它的类名

javadocs中有一个很好的例子:

http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html

API罐

package com.foo;

public interface FooInterface { ... }

public class FooInterfaceFactory {
  public static FooInterface newFooInstance() {
    ServiceLoader<FooInterface> loader = ServiceLoader.load(FooInterface.class);
    Iterator<FooInterface> it = loader.iterator();
    // pick one of the provided implementations and return it.
  }

装订罐

package com.myfoo;
public class MyFooImpl implements FooInterface { ... }

META-INF/com.foo.FooInterface
    com.myfoo.MyFooImpl

编辑

SPI示例

public interface FooSpi { 
   void accepts(String url);
   FooInterface getFooInstance();
}


public class FooInterfaceFactory {
  public static FooInterface getFooInterfaceInstance(String url) {
    ServiceLoader<FooSpi> loader = ServiceLoader.load(FooSpi.class);
    Iterator<FooSpi> it = loader.iterator();
    while (it.hasNext()) {
       FooSpi fooSpi = it.next();
       if (fooSpi .accepts(url)) {
         return fooSpi.getFooInstance();
       }
    }

    return null;
  }
}

当然,将文件名更改为com.foo.FooSpi并提供FooSpi的实现。这样您就可以将公共API与Spi接口隔离开来。

如果要隐藏accepts方法,则始终可以有第二个接口,它是您的公共API,并且



 类似资料:
  • 问题内容: 我经常发现用Java-8之前的设置来实现构建器模式很麻烦。总是有很多几乎重复的代码。建造者本身可以被视为样板。 实际上,有一些代码重复检测器,它们几乎会将使用java-8之前版本的工具构建的构建器的每种方法都视为所有其他方法的副本。 因此,请考虑以下类以及它是Java-8之前的构建器: 如何使用java-8工具实现构建器模式? 问题答案: 构建 可变对象 (稍后将讨论不可变对象)的想法

  • 嗨,我是Kotlin世界的新手。我喜欢到目前为止所看到的,并开始考虑将我们在应用程序中使用的一些库从Java转换为Kotlin。 第二次更新:问题是如何用Kotlin中的一些参数为一个简单的pojo编写一个构建器设计模式?下面的代码是我的尝试,方法是编写java代码,然后使用eclipse-kotlin-plugin转换为Kotlin。

  • 我有一个通用接口处理程序 我可以有n个这个接口的实现。假设我现在有以下两个实现。一个处理字符串对象,另一个处理日期 我想写一个工厂,它将根据类类型返回处理程序实例。比如: 我在这个工厂里遇到了以下错误: 类型不匹配:无法从转换为

  • 问题内容: 通过Maven插件运行时,我试图使VertX Mertrics正常工作exec:java。 当我将应用程序打包到fatjar中并使用以下命令运行时,所有工作均按预期进行 当我运行它时,我看到: 我尝试了几种方法: 添加为编译依赖项 创建内部指标实施并通过文件进行注册(请仔细检查其是否已实际复制到 还添加为附加的classpath元素(除了上一点之外) 我已经仔细检查了ServiceLo

  • 问题内容: 所以我目前正在研究for 的实现。我正在使用在http://pastebin.com/nHJDAbH8上找到的示例代码。 (https://www.kraken.com/help/api)描述的一般用法是: = API密钥 =使用HMAC-SHA512的消息签名 和已解码的秘密API密钥 和 =始终增加无符号的64位整数 =两因素密码(如果启用了两因素,则不是必需的) 但是我面临以下回

  • 我一直在努力尝试让Bouncy Castle Scrypt进入我的web应用程序进行密码加密。我对Java编程和安全性相当陌生。 我试着查看了Bouncy Castle的Scrypt类文档。然而,我真的很难弄清楚它是如何工作的。它似乎并没有真正给出如何创建类或诸如此类的信息。 我在Stack Exchange和Google上搜索了一下,看看是否有什么地方可以给出一个很好的示例,说明我应该做什么来创