OSGi 类加载:为什么 BND 导入未直接引用的 类?

OSGi classloading: why does BND imports classes that are not referenced directly?

捆绑包-A:

FooA.java

package com.foo.a;

import com.foo.b.FooB;

class FooA {
    FooB b = new FooB();
}

B 组:

FooB.java:

package com.foo.b;

import com.foo.c.FooC;

class FooB {

    public FooC foo() {
       ...
    }
}

Bundle-C: ...

简而言之,我有 3 个捆绑包 - A、B 和 C。

Bundle A 直接引用 Bundle B,Bundle B 引用 C。 如您所见,FooA 没有使用 FooB 中 returns FooC 中的方法,因此 FooC 未直接在 bundle A 中引用。

为什么 BND 将 OSGi 导入包包含到 com.foo.c? 我理解它的方式 - 捆绑包 A 只需要捆绑包 B 才能自行解决。另一方面,Bundle B 需要 C。但是如果 A 没有在那里使用它,为什么要直接需要 C?

我认为 bnd 为您使用的 classes 导入所有对外部可见的 classes。当您使用 class FooB 时,您可能需要访问它可能需要的所有 classes 作为参数或 return 作为结果。

如果您想避免依赖性,您可以创建一个只显示您真正需要的方法的界面。然后,您可以在 bundle B 中使用该接口创建一个服务,并且仅使用 bundle A 中的接口访问该服务。

查看 FooA 的字节码 class。您会以某种方式在其中看到 FooC。使用一个 Java 反编译器工具,看看为什么要使用它。一些反编译器创建的代码比原始 java 代码显示更多信息。我在这里看不出为什么,但这是另一个例子:

猜猜你有以下功能:

public class ListProvider {

    public static ArrayList getMyList() { return null; }

}

其他class这样称呼它:

List myVar = ListProvider.getMyList();

你会在另一个class的字节码中看到ArrayList。原因是字节码 leven 上使用的函数签名也包含 return 类型。