我目前正在编写一个在OSGi环境中运行的应用程序。
对于可视化部分,我使用的是JavaFX。每个 UI 元素都是扩展边框窗格的可停靠视图。它的内容是使用 fxml 文件中的 fx:root 元素描述的。其中一些 UI 元素需要访问 OSGi 容器中的服务(例如,视图中的按钮可能会触发需要引用 PersistenceService 的保存操作)。
实现这一目标的最佳方法是什么?
UI 元素由我使用的框架自动生成。 访问服务的唯一方法是BundleActivator
或静态方法FrameworkUtil.getBundle()
。
我的方法是使用静态实用程序方法,但是在网上阅读了更多内容后,我意识到您通常不想针对OSGi本身进行编码。
另一种解决方案是使用 Apache Felix 提供的 scr 注释。将 UI 元素标记为 @Component
并通过 @Reference
引用每个所需的服务将起作用。但这是好的做法吗?我应该给它们做注释吗?我总是认为@Component
引用的类是由OSGi本身管理的,并且将始终由OSGi实例化。
首先,如果你想直接在Java Code中声明/引用你的服务,你应该考虑使用ServiceTracker来避免ServiceReference性质的许多问题。
SCR注释是一个很好的方法,另一个(对已经使用Spring或蓝图的遗留项目更友好)是直接使用蓝图,或者如果你想要spring功能Spring osgi纲要,并在标准注释@Named/@Component,@Inject/@Autowired <service>
和<reference>
注入豆子。
最后一个选项的主要好处是,像 Karaf 这样的容器可以自动加载你的 spring 配置(考虑到它在 META-INF/spring/*.xml 文件中)和注册/引用服务。
例如,您可以使用蓝图引用列表轻松实现白板模式,并跟踪针对特定接口公开的所有服务。
对于注释,我确实认为争论更多的是关于"注释与配置文件",而不是与OSGi有关。我个人认为这是在将您的实现与其他 API 绑定的侵入性注释之间进行选择的问题,而其他解决方案(例如外部.xml配置文件)的侵入性较小。但最终,这比OSGi更像是一个大讨论。请参阅此其他线程。