我可以在其他捆绑包发布的Blueprint服务前面注入代理吗? [英] Can I inject proxies in front of Blueprint services published by other bundles?

查看:109
本文介绍了我可以在其他捆绑包发布的Blueprint服务前面注入代理吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We are using Karaf and a number of OSGI Blueprint services to implement a system.

是否可以制作一个BundleListener类型的包,当它存在于 OSGI container,用代理装饰我们的 Blueprint服务所以引用这些服务的捆绑包会调用代理吗?

Is it possible to make a "BundleListener" type of bundle that, when present in the OSGI container, decorates our Blueprint services with a proxy so bundles referring these services will call the proxy instead?

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

(I guess this could be accomplished either by somehow adding the proxy in front of the service already in the Service Registry, or by changing the reference obtained by the referring bundle - ServiceTracker.addingService style)

推荐答案

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

The standard way to do these hacks is to use the service hooks in the OSGi core framework. The hooks allow you to remove a service from the view of one or more bundles. You can then register another service that proxies the first service and that is not removed from the bundle's view.

现有:

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

Proxied

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

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

Though at first a bit odd, this "remove from view" capability allows you to control in detail what service a bundle is exposed to while keeping the overall complexity minimal. See chapter 55 in the OSGi 5.0.0 Core. Section 55.3.1 details this proxying.

< soapbox>

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

I call these things hacks because proxies this way have bad runtime temporal ordering qualities. If your manager bundle (the one that hides and creates the proxies) is started later than the bundle using the service you're in trouble since the using bundle is temporarily exposed to the non-proxied service.

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

Though there are ways you to solve start ordering this problem, they all basically suck since you now have a undeclared (ordering) dependency. It is thus MUCH better to ensure that the bundle that uses the proxy has a special dependency, like another service type or a special service property. Since the dependency then is explicit, you have no more worries about ordering, the temporal dependency has now become an ordinary service dependency problem which is handled very well by DS and other service managers in OSGi.

使用属性/其他类型代理

Using property/other type to proxy

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

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

You obviously do not want to modify the bundle that registers the service nor the bundle that uses the service since this would kill the whole idea of a reusable aspect. The programmers of the registering/using bundles should be blissfully unaware of the manager's scheme. So how do you se the filter on the using bundle?

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

If you use Declarative Services (DS), then you're in luck! With DS you can set a filter on a service reference through Configuration Admin with the 'target.' configuration property. So the manager bundle sees a service to be proxied, it registers a second service with a special property (e.g. 'proxied=true'). The using bundle then has a filter set through Configuration Admin DS' target reference property like '(proxied=*)'.

< / soapbox> ;

这篇关于我可以在其他捆绑包发布的Blueprint服务前面注入代理吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆