java - OSGi 中仅运行时依赖项的最佳实践
问题描述
根据开闭原则,我通常以这样一种方式设计我的 Java 包和库,即有一个通用的“接口”或“API”包/库和一个或多个实现(非常类似于许多常见的 API,如 JDBC或 JAXP/SAX)。为了在不违反 OCP 的情况下在基础 API 库中定位一个实现(或有时是多个实现),我通常使用 Java 的ServiceLoader机制,或者偶尔通过ClassGraph或Reflections等第三方库进行类路径扫描。从 Maven 的角度来看,实现是作为runtime
依赖项引入的(因为它们仅在执行时需要,而不是在编译时需要)。很标准的东西。
所以,现在,我想将其中一些包作为 OSGi 包提供(API 和实现在单独的包中),但由于在 OSGi 中每个包都有自己的类加载器,因此类路径扫描和ServiceLoader
API 都不能用于此目的。乍一看,OSGi 的“片段”机制似乎与上述纯 Java 设置最接近。在这种情况下,API 包将是“片段主机”,具体实现将作为片段附加到该主机包。由于片段宿主及其所有附加片段使用相同的类加载器,标准的纯 Java 机制如ServiceLoader
或者 ClassGraph 仍然可以想象。这还有一个优点,那就是不需要检测库/包是否在 OSGi 上下文中运行,并且不需要 OSGi 框架依赖项。
所以,简而言之,我的问题是:片段是在 OSGi 中实现仅运行时依赖项的正确方法,还是有更好(或更标准)的方法?最好,我正在寻找一种在 OSGi 容器中工作但不需要依赖于 OSGi 本身的解决方案。
解决方案
没有片段在翻译之外几乎总是错误的。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;
}
...
}
推荐阅读
- arrays - Powershell通过开始和结束字符将字符串拆分为数组
- powerbi - 在 Power BI 中按 DESC 顺序对日期筛选器进行排序
- vue.js - Vue中对象的嵌套for循环
- docker - Dockerfile FROM AS 抛出无效的参考格式
- python - FyPi 中的耦合非线性方程组
- python - MechanicalSoup:无法登录 gmail
- python-3.x - 从现有 DataFrame 制作 DataFrame 的更快代码
- reactjs - React 避免功能组件的重新渲染
- c - 将节点移动到链表中的新索引
- javascript - 如何将此 Javascript 验证应用于多个数字字段?