多くの場合、カスタムサービスに高いランキングを割り当てると、コンポーネントは現在のサービスからバインドを解除し、カスタムサービスにバインドするようになります。それ以外の場合、コンポーネントは現在のサービスを使用し続けます。それはなぜでしょう。そして、コンポーネントにサービスを採用させるにはどうしたらよいでしょうか。 コンポーネントのサービス参照ポリシーオプションが、サービスを決定する鍵となります。
ポリシーのオプションは次のとおりです。
greedy
:コンポーネントは、一致する最高ランクのサービスが利用可能になるとすぐに使用します。
reluctant
:コンポーネントは、次のイベント時に利用可能な一致する最高ランクのサービスを使用します。
- コンポーネントが(再)アクティブ化される
- コンポーネントの既存の参照サービスを利用できなくなった
- コンポーネントの参照が、既存のバインドされたサービスと一致しなくなるように変更される
つまり、greedyポリシーオプションを使用した参照では、すぐに上位のサービスが採用されますが、reluctantポリシーオプションを使用した参照では特定のイベントが必要になります。Liferay DXPの[Configuration Admin]では、構成ファイル(コンフィグファイル)またはAPIを使用して、サービス参照の変更をその場で切り替えることができます。ここでは、構成ファイルを使用してカスタムサービスをすぐに使用するようにサービス参照を再構成します。
このチュートリアルでは、サンプルモジュールoverride-my-service-reference
とoverriding-service-reference
を使用して、サービス参照の再構成を示し、コンポーネントを別のサービスにバインドします。モジュールをダウンロードして、Gradle(各モジュールに同梱されている)を使用してビルドするか、チュートリアルの手順を適用して独自のカスタマイズを構成できます。各サンプルモジュールルートでgradlew jar
を実行すると、モジュールJARがbuild/libs
フォルダに生成されます。
-
override-my-service-reference
(ダウンロード):このモジュールのポートレットコンポーネントOverrideMyServiceReferencePortlet
のフィールド_someService
は、タイプがSomeService
のサービスを参照します。参照のポリシーは静的でReluctantです。デフォルトでは、SomeServiceImpl
と呼ばれる実装にバインドします。 -
overriding-service-reference
(ダウンロード):CustomServiceImpl
と呼ばれるカスタムSomeService
実装を提供します。 モジュールの構成ファイルは、CustomServiceImpl
にバインドするようにOverrideMyServiceReferencePortlet
のSomeService
参照をオーバーライドします。
カスタムサービスを対象とするようにコンポーネントのサービス参照を再構成する準備が整いました。
サービス参照の再構成
Liferay DXPの[Configuration Admin]では、構成ファイルを使用して、サービス参照をその場で切り替えることができます。
-
参照コンポーネントにちなんで名付けられたシステム構成ファイルを作成します。命名規則
[component].config
に従って、[component]
をコンポーネント名に置き換えます。 サンプルコンポーネントoverride.my.service.reference.portlet.OverrideMyServiceReferencePortlet
の構成ファイル名は次のとおりです。override.my.service.reference.portlet.OverrideMyServiceReferencePortlet.config
-
構成ファイルに、カスタムサービスでフィルター処理する参照ターゲットエントリを追加します。エントリは次の形式に従ってください。
[reference].target=[filter]
[reference]
をオーバーライドする参照名に置き換えます。[filter]
をカスタムサービスでフィルター処理するサービスプロパティに置き換えます。次の例では、
component.name
サービスプロパティをフィルター処理します。_someService.target="(component.name\=overriding.service.reference.service.CustomServiceImpl)"
次の例では、
service.vendor
サービスプロパティをフィルター処理します。_someService.target="(service.vendor\=Acme, Inc.)"
-
オプションで、参照が使用できるサービスの数を指定する
cardinality.minimum
エントリを追加できます。形式は次のとおりです。[reference].cardinality.minimum=[int]
カーディナリティの最小値の例を次に示します。
_someService.cardinality.minimum=1
-
構成ファイルをフォルダ
[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
を参照して、作業を委任しています。
Liferay DXPは構成ファイルを処理し、サービス参照を挿入しました。これにより、カスタムサービスが参照コンポーネントにバインドされました。
関連トピック
OSGi Services and Dependency Injection with Declarative Services