2017-08-07 69 views
0

我在使用通過Karaf使用OSGi聲明式服務時加載組件的順序時遇到問題。聲明式服務引用多個引用和依賴關係

予有這種情況:

@Component 
public class A implements IA 
{ 
    doSomething() {...} 
} 


@Component 
public class B implements IB 
{} 

@Component 
public class C implements IC 
{ 
    @Reference 
    IA a 

    @Reference 
    (cardinality = ReferenceCardinality.MULTIPLE, 
    policyOption = ReferencePolicyOption.GREEDY, 
    unbind = "doUnRegister") 
    void doRegister(IB b) 
    { 
    a.doSomething() 
    } 

    void doUnregister(IB b) 
    { 
    ... 
    } 
} 

A,B,和C是三種不同的束。

當啓動Karaf時,B被註冊並且調用doRegister。但是:服務A沒有準備好(a爲空)。

我試過如下:

  1. 組A的啓動級別,以低於B低的東西......沒在工作列表工作
  2. 皮卡B的註冊和實際使用一之後當C被激活時。沒有工作和代碼混亂。
  3. 通過doRegister註釋找到了一個寫這個需求的方法 - 不可能。
  4. 我試圖使用服務定位器並通過C - DID NOT WORK上的激活方法獲取上下文,它使Karaf崩潰。

我必須明確地遺漏一些東西,有沒有人遇到類似的問題,並找到了解決辦法?

UPDATE: 參考文獻A a改爲IA a。在參考文獻B()上添加了被遺忘的信息。

+0

您的示例類是否完整? B可能實現和接口,A不? –

+0

謝謝指出。但是,A,B和C是由接口支持的,問題依然存在。 –

+0

你可以發佈一個完整的小例子到github或類似的嗎? –

回答

0

根據您提供的示例代碼,C不會被激活,直到AB存在,因爲引用AB是靜態的,強制性的引用。所以開始訂購是不相關的。

此外,引用是按照它們寫入組件描述XML的順序設置的。當Bnd將批註處理到組件描述XML中時,它會按參考名稱的順序寫入參考。引用名稱可以明確設置,並且默認爲註釋成員的名稱。因此,在您的示例代碼中,a出現在doRegister之前,因此在調用doRegister之前將設置字段a

我的猜測是,在努力減少實際代碼到這個例子中,你已經失去了一些重要的信息來理解你的問題。這將包括您的參考的靜態/動態和強制性/可選性以及參考名稱。

+0

更新:我更新了示例程序,更詳細地介紹了引用註釋和正確使用接口。 –

+0

ReferenceCardinality.MULTIPLE是0..n。因此,如果組件C在組件B之前啓動,那麼C的引用將很樂意被零Bs滿足。此外,如果查看爲組件C生成的組件描述XML,則應該看到字段A的引用元素位於綁定方法doRegister的引用元素之前。這意味着在B被綁定並且doRegister被調用之前,A將被綁定併成爲一個集合。 –

相關問題