我写过this project并已在我的其他图书馆中使用过它。
然而,我发现有些不对劲。也就是说,在这个库的每个用户中,我创建了一个实用程序类,其唯一的作用是提供一个或多个MessageBundle
。这很糟糕。
我希望在库中内置一个机制,以便让图书馆用户能够注册/调用包。
我的第一个想法是让一个单件工厂使用.register()
和.get()
方法(对重复键进行适当检查等)并从static
初始化块中调用它们。
...但是存在一个问题:无法保证首先调用哪个静态初始化块。
知道我想保持这个库的依赖关系“完整”(这意味着,根本没有外部依赖),你会推荐什么解决方案?
(注意:这是Java 6 +)
答案 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提供程序等)。