“集中”库提供的实例的好方法?

时间:2013-06-01 17:09:05

标签: java

我写过this project并已在我的其他图书馆中使用过它。

然而,我发现有些不对劲。也就是说,在这个库的每个用户中,我创建了一个实用程序类,其唯一的作用是提供一个或多个MessageBundle。这很糟糕。

我希望在库中内置一个机制,以便让图书馆用户能够注册/调用包。

我的第一个想法是让一个单件工厂使用.register().get()方法(对重复键进行适当检查等)并从static初始化块中调用它们。

...但是存在一个问题:无法保证首先调用哪个静态初始化块。

知道我想保持这个库的依赖关系“完整”(这意味着,根本没有外部依赖),你会推荐什么解决方案?

(注意:这是Java 6 +)

1 个答案:

答案 0 :(得分:1)

您可以使用服务提供商的标准支持:ServiceLoader。您只需要库的每个用户提供某个接口的实现,例如

public interface MessageBundleProvider {
    List<MessageBundle> getBundles();
}

实现此接口的类的名称必须在名为META-INF/services/com.example.MessageBundleProvider的用户库的jar文件的文件中指定。

在运行时,您的库将使用以下代码自动发现所有消息包提供者:

private static final ServiceLoader<MessageBundleProvider> LOADER
    = ServiceLoader.load(MessageBundleProvider.class);

private static final List<MessageBundle> BUNDLES;

static { 
    BUNDLES = new ArrayList<MessageBundle>();
    for (MessageBundleProvider provider : loader) {
         for (MessageBundle bundle : provider.getBundles()) {
             BUNDLES.add(bundle);
         }
    }
}

免责声明:我知道ServiceLoader存在,但我以前从未使用过它。这是所有标准Java服务提供程序的发现方式(如JDBC驱动程序,charset提供程序等)。