2017-07-14 78 views
0

我正在使用暴露服務的OSGi應用程序(帶有felix scr註釋)。服務通過傳遞字符串值來向外部API註冊。將運行時參數傳遞給OSGi felix scr註釋中的服務

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,綁定= 「綁定」,解除綁定= 「解除綁定」,referenceInterface = ServiceListener.class) 私人的AtomicReference myServiceListener =新的AtomicReference <>();

如果我嘗試用@Reference其他服務來使用它那麼有沒有規定值傳遞給服務監聽只爲特定的模式變化,使 的服務可以是r通過只傳遞模式列表來監聽而不是所有的東西,從而跨越我的包。因爲激活方法將在服務在使用類(組件)中正確綁定後被調用。 OSGi中是否有任何規定實現此功能?

回答

0

一種方法是爲每個模式創建一個服務。您可以通過提供模式名稱作爲配置值並使用多個配置來完成此操作。然後每個這樣的服務也將具有該配置參數作爲服務屬性。因此,客戶端可以篩選模式屬性。

如果你不想使用這些配置,那麼你可以創建一個提供工廠的服務。然後,每個客戶端都會綁定工廠,並通過在工廠的create方法中提供模式名稱來創建實例。

3

您對應用程序的實際工作方式進行了很少的描述,這使得該問題難以回答。

從你分享的代碼看起來好像你正在遵循一個不好的模式。 Listener模式是許多同步問題和內存泄漏的來源,當您處於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 
} 
相關問題