我指的是“服务提供商框架” 有效Java的第2章, ,这似乎完全是处理我遇到的问题的正确方法,我需要在运行时实例化几个课程之一 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,并且我在罐子中分发它们,是否有任何方法可以使registerProvider自动称为“ registerProvider”,或者我的客户端程序将使用算法的客户程序,或者使用算法必须明确呼叫foooalgorithgorithgorithmregisterprovider(regegisterProverIrs.regecterProvider)(RegregisterProvider)(RegregisterProvider) )对于他们想使用的每个课程?

有帮助吗?

解决方案

我认为您需要创建一个meta-inf/services/firlJAR文件规范 或者 这个).

Java建筑师的实用API设计供词 书第8章是关于SPI的。

ServiceloDoder可能会帮助您列出可用的实现。例如,使用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);
}

其他提示

您可以将客户端罐注册在某些类中的静态初始化器块中,您知道会在 FooAlgorithmRegistry.getProvider(), , 就像是:

static {
    FooAlgorithmRegistry.registerProvider("test", new MyFooAlgorithmProvider());
}

但是,可能很难找到一种方法来确保它将运行(静态初始化器可以在工厂的访问方法之前首次运行一次,只有一次,当课程首次加载时一次运行一次)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top