如何在 OSGi DS 组件中处理不同的@Reference

How to handle different @Reference in OSGi DS Component

我遇到以下情况的问题:服务器正在等待一个或多个函数。绑定函数时,将调用 bindFunction。它需要调用任何 SpecificSystem 的 doSomething()。

当我的 OSGi 容器中没有 SpecificSystem 时,什么也没有发生,这很好,因为系统引用不满足。当我将 SpecificSystem 添加到我的容器时出现问题。在这种情况下,在设置系统引用之前调用 bindFunction,导致 bindFunction 内部出现 NullPointerException。

是否有任何 OSGi 方法来确保在执行 bindFunction 时设置系统引用,以便我可以在 bindFunction 中安全地调用 system.doSomething()?

在您的示例中,系统引用似乎是必需的。在这种情况下,只有存在系统服务时,您的服务器组件才会出现。

您正踏入危险的水域:-)您需要订购。您的代码假定 bindFunction 引用在 system 引用之后调用。

OSGi 规范保证注入按照引用名称的词法顺序进行。 (当然,这仅适用于 available 服务。)

最简单的方法是为引用命名,使 system 引用的名称在词法上低于 bindFunction 引用的名称,例如 asystem_system.注入按词法顺序进行。

这当然很难看。处理此问题的一种方法是注入函数服务并在需要时使用它们,而不是在绑定函数中主动执行某些操作。这让事情变得更懒惰,这几乎总是好的。

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;

@Component(name = "ServerComponent", immediate = false)
public class Server {

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    System system;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected void bindFunction(Function func) {

    }

    @Activate
    public void activate() {

    }   
}

您可以在激活方法中调用doSomething()。 Osgi 使用@Reference 注解保证方法调用顺序。

如果获取了系统和函数引用,激活方法将被OSGi环境调用。您可以在 activate() 方法中调用 system.doSomething() 方法。 @Reference(cardinality = ReferenceCardinality.MANDATORY)注解表示获取到引用后调用activate方法