-->

简单的Java“服务提供者框架”?(Simple Java “Service Provider fr

2019-06-26 05:23发布

我指的是在讨论“服务提供商框架” 有效的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被自动调用,或将使用该算法我的客户端程序必须显式调用FooAlgorithmRegistry.registerProvider( )他们想要使用的每个类?

Answer 1:

我认为你需要创建一个META-INF /服务/ fully.qualified.ClassName和列表的东西,但我不记得规范( JAR文件规范或本 )。

一个Java架构师书第8实用API设计的供述是关于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);
}


Answer 2:

你可以让客户端JAR中的一些类,你知道之前将被称为内的静态初始化块注册商FooAlgorithmRegistry.getProvider()是这样的:

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

但是,它可能是非常难以找到一种方法来保证,这将运行(静态初始化保证是一次只运行一次,当首次加载的类)工厂的访问方法之前。



文章来源: Simple Java “Service Provider frameworks”?