看一看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,并且



