java - 我可以在其他包发布的蓝图服务前面注入(inject)代理吗?

标签 java osgi blueprint-osgi

我们正在使用 Karaf 和许多 OSGI Blueprint 服务来实现系统。

是否可以制作一个 "BundleListener" 类型的 bundle ,当它存在于 OSGI 容器中时,用以下方式装饰我们的 Blueprint 服务代理,以便引用这些服务的 bundle 将调用代理?

(我想这可以通过以某种方式在服务注册表中已有的服务前面添加代理来完成,或者通过更改引用包获取的引用 - ServiceTracker.addingService 样式来完成)

最佳答案

执行这些 hack 的标准方法是使用 OSGi 核心框架中的服务 Hook 。这些 Hook 允许您从一个或多个 bundle 的 View 中删除一项服务。然后,您可以注册另一个服务来代理第一个服务,并且该服务不会从 bundle 的 View 中删除。

现有:

  +----------+              +----------+
  | register |------<|------| using    |
  +----------+              +----------+

代理

  +----------+         hide +----------+
  | register |------<|-+--X-| using    |---|>---+ proxied
  +----------+         |    +----------+        |
                       |                        |
                       |    +----------+        |
                       +----|  manager |--------+
                            +----------+

虽然一开始有点奇怪,但这种“从 View 中删除”功能允许您详细控制 bundle 公开的服务,同时保持整体复杂性最小。请参阅 OSGi 5.0.0 Core 中的第 55 章。第 55.3.1 节详细介绍了此代理。

<soapbox>

我称这些东西为黑客,因为这种方式的代理具有较差的运行时时间排序质量。如果您的管理器 bundle (隐藏并创建代理的 bundle )晚于使用该服务的 bundle 启动,那么您就会遇到麻烦,因为使用 bundle 暂时暴露给非代理服务。

虽然有很多方法可以解决开始排序这个问题,但它们基本上都很糟糕,因为你现在有一个未声明的(排序)依赖项。因此,最好确保使用代理的包具有特殊的依赖性,例如另一种服务类型或特殊的服务属性。由于依赖性是显式的,因此您不必再担心顺序,时间依赖性现在已成为一个普通的服务依赖性问题,DS 和 OSGi 中的其他服务管理器可以很好地处理该问题。

使用属性/其他类型进行代理

  +----------+              +----------+    proxied=true
  | register |              | using    |---|>---+ 
  +----------+              +----------+        |
        |                                       |
        |                   +----------+        |
        +-----------<|------|  manager |--------+
                            +----------+

您显然不想修改注册服务的包或使用该服务的包,因为这会破坏可重用方面的整个想法。注册/使用包的程序员应该幸福地不知道经理的计划。那么如何在 using 包上设置过滤器呢?

如果您使用声明式服务 (DS),那么您很幸运!使用 DS,您可以通过配置管理使用“目标”对服务引用设置过滤器。配置属性。因此,管理器包看到要代理的服务,它会使用特殊属性(例如“proxied=true”)注册第二个服务。然后,使用的 bundle 会通过配置管理 DS 的目标引用属性设置一个过滤器,例如“(proxied=*)”。

</soapbox>

关于java - 我可以在其他包发布的蓝图服务前面注入(inject)代理吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16341488/

相关文章:

java - Apache Camel - 从文件读取 JDBC 数据源属性

ssl - Camel iMap - 忽略 SSL 证书

java - 从 Java 程序中存储/读取敏感数据

java - UnsatisfiedLinkError 在 Mac 上的 Eclipse 中使用 JavaCV

osgi - 使 Sonar Runner Gradle 任务依赖于我的一项任务

java - Pax-import-bundle 和 Spring DM 包

java - 通过 GAE 进行 http 请求时,GAE 是否缓存数据?

java - 为什么这个java计算器给我这个答案?

java - OSGi如何安装两个相同的包?

java - 如何在camel蓝图中引用 "disable"bean?