问题描述
进行这些黑客攻击的标准方法是使用OSGi核心框架中的服务挂钩。挂钩允许您从一个或多个捆绑包的视图中删除服务。然后,您可以注册另一个服务来替代第一个服务,并且该服务不会从捆绑软件的视图中删除。
现有:
+----------+ +----------+
| register |------<|------| using |
+----------+ +----------+
代理的
+----------+ hide +----------+
| register |------<|-+--X-| using |---|>---+ proxied
+----------+ | +----------+ |
| |
| +----------+ |
+----| manager |--------+
+----------+
尽管乍一看有些奇怪,但这种“从视图中删除”功能使您可以详细控制捆绑包所提供的服务,同时将总体复杂性降至最低。请参阅OSGi 5.0.0 Core中的第55章。第55.3.1节详细介绍了此代理。
<soapbox>
我称这些事情为骇客,因为这种方式的代理具有不良的运行时时间排序质量。如果您的经理捆绑包(用于隐藏和创建代理的捆绑包)的启动晚于使用该服务的捆绑包,则您会遇到麻烦,因为使用捆绑包暂时会暴露于非代理服务。
尽管有一些方法可以解决您开始订购此问题的方法,但是由于您现在具有未声明的(订购)依赖性,因此它们基本上都很烂。因此,最好确保使用代理的捆绑包具有特殊的依赖性,例如另一种服务类型或特殊的服务属性。由于依存关系是显式的,因此您不必再担心排序,时间依存关系已成为一个普通的服务依存关系问题,DS和OSGi中的其他服务管理器可以很好地解决此问题。
使用属性/其他类型代理
+----------+ +----------+ proxied=true
| register | | using |---|>---+
+----------+ +----------+ |
| |
| +----------+ |
+-----------<|------| manager |--------+
+----------+
您显然不想修改注册该服务的捆绑包或使用该服务的捆绑包,因为这将杀死可重用方面的整个想法。注册/使用捆绑软件的程序员应该很高兴不知道经理的方案。那么,如何在使用包中设置过滤器?
如果您使用声明式服务(DS),那么您很幸运!使用DS,您可以通过Configuration Admin使用“目标”对服务参考设置过滤器。配置属性。因此,管理器捆绑包看到要代理的服务,它注册了具有特殊属性的第二个服务(例如’proxied = true’)。然后,使用包通过Configuration Admin DS’目标引用属性(例如’(proxied = *)’)设置了过滤器。
</soapbox>
解决方法
我们正在使用Karaf
和许多OSGI Blueprint services
实现一个系统。
是否可以制作一种"BundleListener"
类型的捆绑包,当其存在于OSGI
容器中时,Blueprint
services
用代理来装饰我们的捆绑包,以便引用这些服务的捆绑包将改为调用代理?
(我想这可以通过以某种方式在Service
Registry中已经存在的服务之前添加代理来实现,也可以通过更改由引用包获得的引用来实现ServiceTracker.addingService
)