我在 Maven 模块 A 中定义了一个 SPI 接口。在模块 B(一个 spring-boot 应用程序)中,我定义了META-INF/services/<interface-named-file>.
在模块 A中,我有这段代码。
public class NotificationResultPluginProvider {
private static NotificationResultPluginProvider notificationResultPluginProvider;
private NotificationResultPlugin notificationResultPlugin;
private NotificationResultPluginProvider() {
final ServiceLoader<NotificationResultPlugin> loader = ServiceLoader.load(NotificationResultPlugin.class);
final Iterator<NotificationResultPlugin> it = loader.iterator();
if (it.hasNext()) {
notificationResultPlugin = it.next();
}
}
public static synchronized NotificationResultPluginProvider getInstance() {
if (null == notificationResultPluginProvider) {
notificationResultPluginProvider = new NotificationResultPluginProvider();
}
return notificationResultPluginProvider;
}
public NotificationResultPlugin getNotificationResultPlugin() {
return notificationResultPlugin;
}
}
Run Code Online (Sandbox Code Playgroud)
在模块 B - spring boot 应用程序 - 我有一个NotificationResultPlugin接口的实现。
现在这是泡菜。
当我从 intellij 运行启动应用程序时,我看到(在下面的代码中)it.hasNext()是true并且notificationResultPlugin已找到。在这种情况下,我的应用程序按预期工作。
if (it.hasNext()) {
notificationResultPlugin = it.next();
}
Run Code Online (Sandbox Code Playgroud)
但是当我使用 CLI 运行启动应用程序时,使用如下命令(注意我首先对 jar 进行放气,然后启动)
jar -xf <jar file>;
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=12341 -cp 'BOOT-INF/lib/*:BOOT-INF/classes' <main/class/fqn>;
Run Code Online (Sandbox Code Playgroud)
然后it.hasNext()是false,我在模块 B 中针对给定 SPI 的实现未找到。结果,我的应用程序没有按预期工作。我现在束手无策了。
其他相关信息:
我的 Spring Boot 应用程序不是 Web 应用程序。也就是说,我没有暴露任何休息终点。我只是spring-kafka以最小的依赖性使用。
我缺少什么?任何帮助表示赞赏。
找到解决方案
正如他们所说,当你不去尝试时,头脑会发挥最佳作用。
ServiceLoader 无法加载 SPI 实现,因为META-INF/services在我启动应用程序时目录不在类路径中。正确设置类路径就可以了。因此,这就是我需要做的改变。
-cp 'BOOT-INF/lib/*:BOOT-INF/classes:.'
请注意末尾的额外点。
| 归档时间: |
|
| 查看次数: |
1356 次 |
| 最近记录: |