OSGi 中仅运行时依赖项的最佳实践

Best practices for runtime-only dependencies in OSGi

Open-Closed Principle 一致,我通常设计我的 Java 程序包和库,这样就有一个通用的“接口”或“API”package/library 和一个或多个实现(非常类似于许多常见的 API,如 JDBC 或 JAXP/SAX)。 为了在不违反 OCP 的情况下在基础 API 库中找到一个实现(有时是多个实现),我通常使用 Java 的 ServiceLoader mechanism, or occasionally classpath scanning via third-party libraries like ClassGraph or Reflections。从 Maven 的角度来看,实现是作为 runtime 依赖项引入的(因为它们只在执行时需要,而不是在编译时)。相当标准的东西。

所以,现在,我想将其中一些包作为 OSGi 包提供(使用 API 并在单独的包中实现),但是因为在 OSGi 中每个包都有自己的 class 加载器, class 路径扫描和 ServiceLoader API 都不会用于此目的。乍一看,OSGi 的“片段”机制似乎最接近上述的 plain-Java 设置。在那种情况下,API 包将是“片段主机”,具体实现将作为片段附加到该主机包。由于片段宿主及其所有附加片段使用相同的 class 加载器,标准的普通 Java 机制如 ServiceLoader 或 ClassGraph 可以想象仍然有效。这还有一个好处,即无需检测 library/bundle 在 OSGi 上下文中是否为 运行,并且不需要 OSGi 框架依赖性。

所以,简而言之,我的问题是:片段是在 OSGi 中实现仅运行时依赖项的正确方法还是有更好(或更标准)的方法?最好,我正在寻找一种在 OSGi 容器中工作但不需要依赖 OSGi 本身的解决方案。

没有片段在翻译之外几乎总是错误。 OSGi模型是使用services.

接下来的方法就是使用 DS。使用 bnd(在 maven、gradle、ant、sbt 或 Bndtools 中)你可以创建 components。组件是用注入和激活指令注释的普通旧 Java 对象 (POJO)。您可以使这些组件在构造函数中获取其所有依赖项。

bnd 代码使用注释生成一个 XML 文件,该文件在运行时用于创建、激活、注入和注册这些组件。这将在 OSGi 框架中开箱即用。注释是构建时间,因此它们不会在您的运行时创建依赖项。

在您的非 OSGi 环境中,您需要自行调用该构造函数。因此,您使用服务加载器收集依赖项,然后以正确的顺序构建它们。

@Component
public class MyComponent implements Foo {

      final Bar bar;

      @Activate
      public MyComponent( @Reference Bar bar ) {
        this.bar = bar;
      }
      ...
}