Spring Boot 应用程序无法加载 SPI 实现

Tya*_*esh 5 java spring-boot

在 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:.'

请注意末尾的额外点。