OSGiサービスを使用するようにコンポーネントを再構成する

多くの場合、カスタムサービスに高いランキングを割り当てると、コンポーネントは現在のサービスからバインドを解除し、カスタムサービスにバインドするようになります。それ以外の場合、コンポーネントは現在のサービスを使用し続けます。それはなぜでしょう。そして、コンポーネントにサービスを採用させるにはどうしたらよいでしょうか。 コンポーネントのサービス参照ポリシーオプションが、サービスを決定する鍵となります。

ポリシーのオプションは次のとおりです。

greedy:コンポーネントは、一致する最高ランクのサービスが利用可能になるとすぐに使用します。

reluctant:コンポーネントは、次のイベント時に利用可能な一致する最高ランクのサービスを使用します。

  • コンポーネントが(再)アクティブ化される
  • コンポーネントの既存の参照サービスを利用できなくなった
  • コンポーネントの参照が、既存のバインドされたサービスと一致しなくなるように変更される

つまり、greedyポリシーオプションを使用した参照では、すぐに上位のサービスが採用されますが、reluctantポリシーオプションを使用した参照では特定のイベントが必要になります。Liferay DXPの[Configuration Admin]では、構成ファイル(コンフィグファイル)またはAPIを使用して、サービス参照の変更をその場で切り替えることができます。ここでは、構成ファイルを使用してカスタムサービスをすぐに使用するようにサービス参照を再構成します。

このチュートリアルでは、サンプルモジュールoverride-my-service-referenceoverriding-service-referenceを使用して、サービス参照の再構成を示し、コンポーネントを別のサービスにバインドします。モジュールをダウンロードして、Gradle(各モジュールに同梱されている)を使用してビルドするか、チュートリアルの手順を適用して独自のカスタマイズを構成できます。各サンプルモジュールルートでgradlew jarを実行すると、モジュールJARがbuild/libsフォルダに生成されます。

  • override-my-service-referenceダウンロード):このモジュールのポートレットコンポーネントOverrideMyServiceReferencePortletのフィールド_someServiceは、タイプがSomeServiceのサービスを参照します。参照のポリシーは静的でReluctantです。デフォルトでは、SomeServiceImplと呼ばれる実装にバインドします。

  • overriding-service-referenceダウンロード):CustomServiceImplと呼ばれるカスタムSomeService実装を提供します。 モジュールの構成ファイルは、CustomServiceImplにバインドするようにOverrideMyServiceReferencePortletSomeService参照をオーバーライドします。

カスタムサービスを対象とするようにコンポーネントのサービス参照を再構成する準備が整いました。

サービス参照の再構成

Liferay DXPの[Configuration Admin]では、構成ファイルを使用して、サービス参照をその場で切り替えることができます。

  1. 参照コンポーネントにちなんで名付けられたシステム構成ファイルを作成します。命名規則[component].configに従って、[component]コンポーネント名に置き換えます。 サンプルコンポーネントoverride.my.service.reference.portlet.OverrideMyServiceReferencePortletの構成ファイル名は次のとおりです。

    override.my.service.reference.portlet.OverrideMyServiceReferencePortlet.config
    
  2. 構成ファイルに、カスタムサービスでフィルター処理する参照ターゲットエントリを追加します。エントリは次の形式に従ってください。

    [reference].target=[filter]
    

    [reference]をオーバーライドする参照名に置き換えます。 [filter]をカスタムサービスでフィルター処理するサービスプロパティに置き換えます。

    次の例では、component.nameサービスプロパティをフィルター処理します。

    _someService.target="(component.name\=overriding.service.reference.service.CustomServiceImpl)"
    

    次の例では、service.vendorサービスプロパティをフィルター処理します。

    _someService.target="(service.vendor\=Acme, Inc.)"
    
  3. オプションで、参照が使用できるサービスの数を指定するcardinality.minimumエントリを追加できます。形式は次のとおりです。

    [reference].cardinality.minimum=[int]
    

    カーディナリティの最小値の例を次に示します。

    _someService.cardinality.minimum=1
    
  4. 構成ファイルをフォルダ[Liferay_Home]/osgi/configsにコピーして、構成をデプロイします。

コンポーネントでscr:infoを実行すると、カスタムサービスが参照にバインドされていることがわかります。

たとえば、scr:info override.my.service.reference.portlet.OverrideMyServiceReferencePortletを実行すると、次の情報が報告されます。

...
Component Description:
Name: override.my.service.reference.portlet.OverrideMyServiceReferencePortlet
...
Reference: _someService
Interface Name: override.my.service.reference.service.api.SomeService
Cardinality: 1..1
Policy: static
Policy option: reluctant
Reference Scope: bundle
...
Component Configuration:
ComponentId: 2399
State: active
SatisfiedReference: _someService
Target: (component.name=overriding.service.reference.CustomServiceImpl)
Bound to:        6841
Properties:
_defaultService.target = (component.name=overriding.service.reference.service.CustomServiceImpl)
component.id = 2398
component.name = overriding.service.reference.service.CustomServiceImpl
objectClass = [override.my.service.reference.service.api.SomeService]
service.bundleid = 525
service.id = 6841
service.scope = bundle
Component Configuration Properties:
_someService.target = (component.name=overriding.service.reference.service.CustomServiceImpl)
...

サンプルコンポーネントの_someService参照は、カスタムサービスコンポーネントoverriding.service.reference.service.CustomServiceImplを対象としています CustomServiceImplはデフォルトのサービスSomeServiceImplを参照して、作業を委任しています。

図1:サンプルコンポーネントのサービス参照は構成ファイルのデプロイによってオーバーライドされるため、ポートレットはカスタムサービスを呼び出していることを示しています。

Liferay DXPは構成ファイルを処理し、サービス参照を挿入しました。これにより、カスタムサービスが参照コンポーネントにバインドされました。

関連トピック

OSGi Services and Dependency Injection with Declarative Services

Finding Extension Points

Using Felix Gogo Shell

« カスタムOSGiサービスの作成言語キーのオーバーライド »
この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています