Java SPI(Java 17模块化系统):如何选择单一实现
Java SPI 选择特定实现的方法
当SPI存在多个实现时,完全可以选择某一特定实现,你写的那段代码是合理且可行的,不过可以做一点语义上的优化:
ServiceLoader.load(SomeService.class) .stream() .map(Provider::get) // 用getClass()匹配比instanceof更严格,避免意外匹配到子类 .filter(s -> s.getClass() == SomeInterfaceImpl2.class) .findFirst() .ifPresent(SomeService::test);
用findFirst().ifPresent()替代limit(1).forEach(),语义会更清晰,明确表达我们只需要第一个匹配的实例并执行对应方法。
另外还有一种更灵活的方案:给SomeService接口新增一个标识方法,返回唯一的服务ID,这样不用硬编码类名,降低代码耦合度:
interface SomeService { public void test(); // 新增服务标识方法 String getServiceId(); } // 实现类中实现标识方法 public class SomeInterfaceImpl2 implements SomeService { @Override public String getServiceId() { return "service-impl-2"; } // ...其他业务实现 }
之后筛选时就可以通过标识匹配:
ServiceLoader.load(SomeService.class) .stream() .map(Provider::get) .filter(s -> "service-impl-2".equals(s.getServiceId())) .findFirst() .ifPresent(SomeService::test);
这种方式更适合需要动态切换实现的场景,不用修改筛选逻辑,只需要调整实现类的标识或者配置即可。
内容的提问来源于stack exchange,提问作者treo
相关产品推荐
相关产品推荐

