【问题标题】:Best practices for runtime-only dependencies in OSGiOSGi 中仅运行时依赖项的最佳实践
【发布时间】:2020-10-22 11:42:25
【问题描述】:

根据Open-Closed Principle,我通常以这样一种方式设计我的 Java 包和库,即有一个通用的“接口”或“API”包/库和一个或多个实现(非常类似于许多常见的 API像 JDBC 或 JAXP/SAX)。 为了在不违反 OCP 的情况下在基本 API 库中定位一个实现(或有时是多个实现),我通常使用 Java 的 ServiceLoader 机制,或者偶尔通过 ClassGraphReflections 等第三方库进行类路径扫描。从 Maven 的角度来看,实现是作为 runtime 依赖项引入的(因为它们仅在执行时需要,但在编译时不需要)。很标准的东西。

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

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

【问题讨论】:

    标签: java osgi dependency-management loose-coupling osgi-fragment


    【解决方案1】:

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

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

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

    在您的非 OSGi 环境中,您将负责自己调用该构造函数。因此,您使用 Service Loader 收集依赖项,然后以正确的顺序构建它们。

    @Component
    public class MyComponent implements Foo {
    
          final Bar bar;
    
          @Activate
          public MyComponent( @Reference Bar bar ) {
            this.bar = bar;
          }
          ...
    }
    

    【讨论】:

    • 感谢您的详细回答,@PeterKriens。我完全忘记了 OSGi 的声明式服务。您建议的解决方案至少需要添加对org.osgi.service.component.annotations 的依赖项,但这可能是一个可以接受的折衷方案(尽管我希望做一些更像 Eclipse 的 Orbit 存储库中的捆绑包,即带有 OSGi 清单的 JAR,否则与它们的非 OSGi 对应物相同)。
    • 在我接受这个答案之前,您是否介意澄清一下为什么片段“在翻译之外几乎总是错误的”?我的理解是,片段旨在用于现有捆绑包的“扩展”。例如,我的一个预期用例是具有低效默认实现的基本/API 包,以及提供更高效解决方案的扩展包(在依赖项方面也更重,所以不是每个人都可能选择那个)选项)。翻译/I18N 真的是片段的唯一合法使用吗?不正确使用碎片有什么坏处?
    • 片段是在标准 java 的类加载器泥泞中长大的人们的警笛之歌。它们提供了一个可识别的环境,但也扼杀了 OSGi 的强大模块化。 IE。正试图吃掉你的蛋糕,并且也拥有它。有时它会起作用,但总的来说,我看到它们非常痛苦,因为它们打开了系统的其余部分拼命试图让它们关闭的栅栏。有一些用途,但由于它们从来都不是真正需要的,所以从没有它们开始。
    猜你喜欢
    • 2011-10-15
    • 2019-08-24
    • 2011-08-16
    • 2020-08-07
    • 2018-03-03
    • 2011-06-11
    • 2010-12-11
    • 2012-10-09
    相关资源
    最近更新 更多