我可以在其他捆绑包发布的Blueprint服务前面注入代理吗?

时间:2013-05-02 15:05:45

标签: java osgi blueprint-osgi

我们正在使用Karaf和一些OSGI Blueprint services来实施系统。

是否可以制作"BundleListener"类型的捆绑包,当OSGI容器中存在时,使用代理装饰我们的Blueprint services,因此引用这些服务的捆绑包将调用代理?

(我想这可以通过以某种方式在服务注册表中已经存在的服务之前添加代理,或者通过更改引用包获得的引用来实现 - ServiceTracker.addingService样式)

2 个答案:

答案 0 :(得分:1)

执行这些攻击的标准方法是使用OSGi核心框架中的服务挂钩。钩子允许您从一个或多个包的视图中删除服务。然后,您可以注册代理第一个服务但未从捆绑包视图中删除的另一个服务。

现有:

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

代理

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

虽然起初有点奇怪,但这种“从视图中删除”功能允许您详细控制捆绑服务所接受的服务,同时保持总体复杂性最小化。请参阅OSGi 5.0.0 Core中的第55章。第55.3.1节详细介绍了此代理。

<soapbox>

我将这些东西称为hacks,因为代理以这种方式具有错误的运行时间排序质量。如果您的管理器捆绑包(隐藏和创建代理的捆绑包)比使用该服务的捆绑包更晚启动,则因为使用捆绑包暂时暴露给非代理服务。

虽然你有办法解决这个问题的开始排序,但它们基本上都很糟糕,因为你现在有一个未声明的(排序)依赖。因此,确保使用代理的bundle具有特殊依赖性(如另一种服务类型或特殊服务属性)会更好。由于依赖性是明确的,你不再担心排序,时间依赖现在已成为一个普通的服务依赖问题,由OS和其他服务经理在OSGi中处理得非常好。

使用属性/其他类型代理

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

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

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

</soapbox>

答案 1 :(得分:0)

虽然没有作为代理实现,但是蓝图拦截器可能会做你想要的;您可以在调用原始bean之前或之后拦截方法调用。我认为这是你用你的代理做的事情。在卡拉夫实施的白羊座蓝图应该肯定支持拦截器。但是,我无法在Aries源本身之外找到好的文档或示例,这使得这个答案没有我希望的那么有用!