簡體   English   中英

將運行時參數傳遞給OSGi felix scr批注中的服務

[英]Pass runtime parameters to service in OSGi felix scr annotations

我正在開發公開服務的OSGi應用程序(帶有felix scr批注)。 該服務通過傳遞字符串值來向外部api注冊。

listener.addSchemaChangeListener(new ChangeListener()
{
    @Override
    public void schemaChange(ChangeEvent changeEvent)
    {
        String schemaName = changeEvent.getSchemaName();

        if (null != myBuilder && schemaList.contains(schemaName))
        {
            initVariables();
        }
    }
}, "SCHEMA1");

服務使用上面的代碼為多個值“ SCHEMA1”,“ SCHEMA1”,“ SCHEMA3”注冊偵聽器……我打算在各種捆綁軟件中重用此服務。 但是我只想聽SCHEMA1的更改,而不是全部。

@Reference(名稱=“ ServiceListener”“,策略= ReferencePolicy.DYNAMIC,基數= ReferenceCardinality.MANDATORY_UNARY,bind =” bind“,unbind =” unbind“,referenceInterface = ServiceListener.class)私有AtomicReference myServiceListener = new AtomicReference <>() ;

如果我嘗試在具有@Reference的其他服務中使用它,則沒有提供將值傳遞給服務以僅偵聽特定架構更改的規定,因此可以通過僅傳遞架構的列表而不是偵聽來在我的捆綁軟件中重新使用該服務所有。 因為一旦在使用類(組件)中正確綁定了服務,就會調用activate方法。 OSGi中是否有任何規定可以實現此功能?

您幾乎沒有包含有關您的應用程序實際工作方式的描述,這使該問題難以回答。

從您共享的代碼來看,您似乎遵循的是錯誤的模式。 偵聽器模式是許多同步問題和內存泄漏的根源,當您使用OSGi時,應該首選白板模式。

白板圖案非常簡單。 倒置模型,而不是讓每個偵聽器查找服務並向其注冊。 事件源(在這種情況下,架構發生更改)將查找在OSGi服務注冊表中注冊的偵聽器服務。 這樣,偵聽器易於編寫和過濾,並且不會在代碼中造成混亂且容易出錯的添加/刪除偵聽器邏輯。

更好的模型將使用服務屬性來選擇特定的架構,並看起來像這樣(使用標准OSGi注釋)。

偵聽器1(偵聽SCHEMA1的更改)

@Component(
    property="schemaName=SCHEMA1")
public class MyListener implements ChangeListener {
    // Your implementation in here
}

偵聽器2(偵聽SCHEMA1,SCHEMA2和SCHEMA3的更改)

@Component(
    property={"schemaName=SCHEMA1",
              "schemaName=SCHEMA2",
              "schemaName=SCHEMA3"})
public class MyListener implements ChangeListener {
    // Your implementation in here
}

Schema1的示例事件源:

@Component
public class MyListener implements ChangeListener {

    @Reference(policy=DYNAMIC, target="(schemaName=SCHEMA1)")
    private final List<ChangeListener> listeners = new CopyOnWriteArrayList<>();

    private void onSchemaChange(ChangeEvent event) {
        listeners.forEach(l -> l.schemaChange(event);
    }

    // Rest of your implementation in here
}

一種方法是為每個架構創建一個服務。 您可以通過提供架構名稱作為配置值並使用多個配置來實現。 然后,每個此類服務還將具有此配置參數作為服務屬性。 因此,客戶端隨后可以篩選架構屬性。

如果您不想使用這些配置,則可以創建一項提供工廠的服務。 然后,每個客戶端將綁定工廠並通過在工廠的create方法中提供架構名稱來創建實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM