我指的是“服务提供商框架”,如中讨论的,这似乎是处理我遇到的问题的正确方法,我需要在运行时实例化几个类之一,基于String
选择哪个服务,以及Configuration
对象(本质上是一个 XML 片段):
但是我如何让各个服务提供商(例如一堆默认提供商+一些自定义提供商)自行注册?
interface FooAlgorithm
{
/* methods particular to this class of algorithms */
}
interface FooAlgorithmProvider
{
public FooAlgorithm getAlgorithm(Configuration c);
}
class FooAlgorithmRegistry
{
private FooAlgorithmRegistry() {}
static private final Map<String, FooAlgorithmProvider> directory =
new HashMap<String, FooAlgorithmProvider>();
static public FooAlgorithmProvider getProvider(String name)
{
return directory.get(serviceName);
}
static public boolean registerProvider(String name,
FooAlgorithmProvider provider)
{
if (directory.containsKey(name))
return false;
directory.put(name, provider);
return true;
}
}
例如如果我编写自定义类 MyFooAlgorithm 和 MyFooAlgorithmProvider 来实现 FooAlgorithm,并将它们分发到 jar 中,是否有任何方法可以自动调用 registerProvider,或者使用该算法的客户端程序必须显式调用 FooAlgorithmRegistry.registerProvider()对于他们想要使用的每个类?
我认为您需要创建一个 META-INF/services/filled.qualified.ClassName 并在那里列出内容,但我不记得规范(JAR 文件规范 http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html or this http://www.velocityreviews.com/forums/t152645-how-is-spi-service-provider-interface-works.html).
The 一位 Java 架构师的实用 API 设计自白本书第8章是关于SPI的。
ServiceLoader 可能会帮助您列出可用的实现。例如使用 PersistenceProvider 接口:
ServiceLoader<PersistenceProvider> loader =
ServiceLoader.load(PersistenceProvider.class);
Iterator<PersistenceProvider> implementations = loader.iterator();
while(implementations.hasNext()) {
PersistenceProvider implementation = implementations.next();
logger.info("PersistenceProvider implementation: " + implementation);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)