我对 Java很陌生(来自 C# .NET 背景)。尝试通过结合使用 Google Guice 和 ServiceLoader 创建“扩展/IoC”样式架构,但似乎无法让 ServiceLoader 部分运行 Java 1.7.0_75 和 IntelliJ IDEA 14。
我的项目中有一个模块,它实际上是一个名为 ViProJ.Bcl 的基类库,其中包含一个名为 com.vipro.bcl.SimplePluginLoader 的接口。
我有另一个名为 ViProJ.TestModules 的模块,它包含一个名为 com.vipro.test.TestModule1 的 SimpleModuleLoader 实现。
在我的 src 文件夹中有一个资源文件夹(在模块设置屏幕中标记为资源),其中包含一个名为 META-INF.services 的文件夹,其中包含一个名为 com.vipro.bcl.SimpleModuleLoader 的文件。此文件中的值为 com.vipro.test.TestModule1。
我有两个由 IntelliJ 创建的工件(在同一目录中),第一个是一个具有从命令行运行的 Main 函数的模块。它像这样加载服务加载器:
ServiceLoader<SimpleModuleLoader> loader = ServiceLoader.load(SimpleModuleLoader.class);
另一个是前面提到的测试库。当我对此进行调试时,服务加载器不包含任何类,因此类的导出不起作用。
当我在 7zip 中打开 jar 文件时,我可以看到 META-INF\services\com.vipro.bcl.SimpleModuleLoader 因此 IntelliJ 已正确打包这些文件。
MANIFEST.MF 文件如下所示:
Manifest-Version: 1.0
Export-Package: com.google.inject.name;version="1.3",com.google.inject
.binder;version="1.3",com.google.inject.spi;version="1.3",com.google.
inject.matcher;version="1.3",com.google.inject.util;version="1.3",com
.google.inject;version="1.3"
Bundle-Name: guice
Created-By: 1.6.0_23 (Sun Microsystems Inc.)
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
Bundle-Copyright: Copyright (C) 2006 Google Inc.
Ant-Version: Apache Ant 1.7.1
Bundle-Vendor: Google, Inc.
Bundle-Version: 3.0
Bundle-ManifestVersion: 2
Bundle-Description: Guice is a lightweight dependency injection framew
ork for Java 5 and above
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-SymbolicName: com.google.inject
Import-Package: javax.inject,org.aopalliance.intercept
Bundle-DocURL: http://code.google.com/p/google-guice/
不太确定为什么清单是在谈论 Guice 而不是我的模块?可能不会导致此失败?谁能告诉我为什么这不起作用?我确定我没有给你你需要的一切,但不确定我还应该在这里包括什么?
这些模块Module
使用 .impl 文件而不是 pom.xml (Maven) 进行构建,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="ViProJ.Bcl" />
<orderEntry type="library" name="guice-3.0" level="project" />
<orderEntry type="library" name="guice-multibindings-3.0" level="project" />
</component>
</module>
我的注入代码使用 MultiBinder,如下所示:
// dynamic modules via service loader
Multibinder<IModule> modBinder = Multibinder.newSetBinder(binder(), IModule.class);
ServiceLoader<SimpleModuleLoader> loader = ServiceLoader.load(SimpleModuleLoader.class);
for (SimpleModuleLoader moduleLoader : loader) {
for (Class<? extends IModule> moduleClass : moduleLoader.getModules()) {
System.out.print("Found expansion module");
modBinder.addBinding().to(moduleClass);
}
}