简体   繁体   English

OSGI关于Glassfish的捆绑软件间通信

[英]OSGI Inter-bundle Communication on Glassfish

I am trying to move from some custom OSGI platform to Glassfish for ease of maintenance and implementing new bundles quicker. 我正在尝试从某些自定义OSGI平台迁移到Glassfish,以简化维护并更快地实现新的捆绑软件。

I came up with a problem while migrating. 我在迁移时遇到了一个问题。 So I have BundleA and BundleB, which are supposed to communicate via Service References. 因此,我有BundleA和BundleB,它们应该通过服务引用进行通信。 The interface for the reference is on BundleC, which is the main bundle on the custom platform. 参考的接口位于BundleC上,BundleC是自定义平台上的主要包。 Without BundleC nothing will start, including the platform itself. 没有BundleC,包括平台本身在内的一切都不会启动。 So I have put the interface on BundleC. 因此,我将接口放在BundleC上。 BundleB has the class implementing the interface and registering it as a service while it is starting up, and BundleA uses that service. BundleB具有实现接口并在启动时将其注册为服务的类,而BundleA使用该服务。

While moving to Glassfish, as it already provides a proper OSGI platform, I dont need my old BundleC. 迁移到Glassfish时,因为它已经提供了合适的OSGI平台,所以我不需要旧的BundleC。 So after removing BundleC, how to provide a proper inter bundle communication, other than exporting and importing classes or including one bundle for start up? 因此,在删除BundleC之后,除了导出和导入类或包括一个要启动的包之外,如何提供适当的包间通信? I want BundleA and BundleB to be "nearly" independent, not coupled. 我希望BundleA和BundleB是“几乎”独立的,而不是耦合的。

Are there any solutions for this case? 有什么解决方案吗? or I will still need that BundleC as some kinda middle-ware? 还是仍然需要BundleC作为某种中间件?

Assuming you have the following setup: 假设您具有以下设置:

                     Service    
  +-------+                                +-------+
  |   A   |---get------|>---register-------|   B   |
  +-------+             .                  +-------+
      !                 .                     !
      !         [service package]             !
      !                 .                     !
      !             +-------+                 !
      \----import-->|   C   |<---import-------/
                    +-------+

This means there are 2 life cycles. 这意味着有2个生命周期。 First A and B must be resolved against C. C's purpose is to decouple A and B from each other since it contains the only shared part, the interface. 首先必须针对C解决A和B。C的目的是使A和B相互分离,因为它包含唯一的共享部分,即接口。 So from a pure coupling problem this is not at all bad in general and many people recommend it. 因此,从纯粹的耦合问题来看,这通常并没有什么坏处,很多人都推荐它。

However, the problem with this model is that you get lots of puny little bundles only containing the interface (though calling it middleware seems a stretch). 但是,此模型的问题在于,您会得到很多仅包含接口的细小捆绑包(尽管将其称为中间件似乎很麻烦)。

I therefore general pick one of the bundles and make it export the service package. 因此,我一般选择其中一个捆绑包,并使其导出服务包。 The picked bundle must be the provider of the service. 所选择的捆绑包必须是服务的提供者 This is in general the implementer of your service interface (but does not have to be, read the OSGi Semantic Versioning Whitepaper for details). 通常,这是您的服务接口的实现者(但不必一定要阅读《 OSGi语义版本控制白皮书》以获取详细信息)。 The provider is the bundle that fulfills the service contract as defined by the service interface's package. 提供者是履行服务接口程序包所定义的服务合同的捆绑软件。 The provider of the service is likely bundle B. 服务的提供者可能是捆绑包B。

Bundle B would then export the service interface's package. 然后,捆绑软件B将导出服务接口的程序包。 Bundle A imports this package. 捆绑软件A会导入此软件包。 This gives a very nice dependency model: Bundle A depends on the service interface's package but NOT on Bundle B. Any other provider of the interface's package will work as well. 这提供了一个很好的依赖模型:捆绑包A依赖于服务接口的程序包,但不依赖于捆绑包B。接口包的任何其他提供程序也将起作用。 At the same, time, bundle A does not get started until there is at least one provider exporting the package. 同时,直到至少有一个提供程序导出软件包,捆绑软件A才会启动。 So you have a very nice dependency managed solution and need only 2 bundles instead of 3. 因此,您有一个很好的依赖项托管解决方案,只需要2个包,而不是3个。

  +-------+                                +-------+
  |   A   |---get------|>---register-------|   B   |
  +-------+             .                  +-------+
      !                 .                     ^
      !         [service package]             !
      !                 .                     !
      \----import-----------------------------/

In bnd(tools) this is trivial, just add the service package to your Export-Package header, bnd will then copy the package from the class path into bundle B. Make sure you mark the provide checkbox for the package to use the right version range for imports. 在bnd(tools)中这很简单,只需将服务包添加到Export-Package标头中,然后bnd会将包从类路径复制到包B中。请确保选中包的提供复选框以使用正确的版本进口范围。

If I understand your architecture properly I think you're doing the right thing, except that because you're now using Glassfish as your OSGI container, you shouldn't need anything in bundle C except for the definition of your service interface. 如果我正确地理解了您的体系结构,那么我认为您在做正确的事情,除了因为您现在使用Glassfish作为OSGI容器之外,捆绑C中不需要任何东西,除了服务接口的定义。

bundle C - should only define the service interface (not provide an implementation). 包C-仅应定义服务接口(不提供实现)。 bundle B - implements the service interface defined by bundle C and registers itself with the OSGI container as a service provider of that interface. 捆绑软件B-实现捆绑软件​​C定义的服务接口,并向OSGI容器注册自身,作为该接口的服务提供者。

bundle A - depends on the service interface defined in bundle C. 捆绑软件A-取决于捆绑软件C中定义的服务接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM