次の設定があると仮定します。
Service
+-------+ +-------+
| A |---get------|>---register-------| B |
+-------+ . +-------+
! . !
! [service package] !
! . !
! +-------+ !
\----import-->| C |<---import-------/
+-------+
これは、2 つのライフサイクルがあることを意味します。まず、A と B を C に対して解決する必要があります。C の目的は、A と B を互いに切り離すことです。C には唯一の共有部分であるインターフェイスが含まれているためです。したがって、純粋なカップリングの問題から、これは一般的にまったく悪いことではなく、多くの人が推奨しています。
ただし、このモデルの問題点は、インターフェースのみを含む非常に小さなバンドルがたくさんあることです (ただし、ミドルウェアと呼ぶのは無理があります)。
したがって、私は通常、バンドルの 1 つを選択して、サービス パッケージをエクスポートします。選択されたバンドルは、サービスのプロバイダーである必要があります。一般に、これはサービス インターフェイスの実装者です (ただし、そうである必要はありません。詳細については、OSGi Semantic Versioning Whitepaperを参照してください)。プロバイダーは、サービス インターフェイスのパッケージで定義されたサービス コントラクトを満たすバンドルです。サービスのプロバイダーはバンドル B である可能性があります。
バンドル B は、サービス インターフェイスのパッケージをエクスポートします。バンドル A はこのパッケージをインポートします。これにより、非常に優れた依存関係モデルが得られます。バンドル A はサービス インターフェイスのパッケージに依存しますが、バンドル B には依存しません。インターフェイスのパッケージの他のプロバイダーも同様に機能します。同時に、バンドル A は、少なくとも 1 つのプロバイダーがパッケージをエクスポートするまで開始されません。したがって、依存関係が管理された非常に優れたソリューションが得られ、必要なバンドルは 3 つではなく 2 つだけです。
+-------+ +-------+
| A |---get------|>---register-------| B |
+-------+ . +-------+
! . ^
! [service package] !
! . !
\----import-----------------------------/
bnd(tools) では、これは簡単です。サービス パッケージを Export-Package ヘッダーに追加するだけで、bnd はパッケージをクラス パスからバンドル B にコピーします。正しいバージョンを使用するために、パッケージの提供チェックボックスをマークしてください。輸入の範囲。