OSGi DS:为什么在激活之前调用setService

时间:2014-01-17 10:18:31

标签: java osgi

我有一个OSGi DS组件,其中定义了属性,并引用了另一个bundle服务。在setService方法中,我获得了另一个bundle服务的引用并启动了另一个线程。我依赖于component.xml中定义的属性。因此,第一次能够从component.xml文件中读取属性是在bundle调用activated方法并获取ComponentContext的引用之后。现在看来我有严重的计时问题,因为setService在执行activate之前执行。

  • 怎么会这样?如果捆绑包在激活之前如何获得所需的服务引用?
  • 如何在setService方法中启动线程时访问component.xml中定义的属性?

具体例子:

private String publishingUrl = "http://0.0.0.0:11023/ws"; // default address

protected synchronized void activate(ComponentContext context) {
    this.ctx = context;
    if (ctx != null) {
        String url = String.valueOf(ctx.getProperties().get("publishingUrl"));
        if (url != null) publishingUrl = url;
    }
    logger.info("Activated and got the publishingUrl: "+ publishingUrl);
}

public void setService(AnotherService service) {
    synchronized (this) {
        if (this.anotherService == service) {
            logger.info("anotherService was already set.");
            return;
        } else {
            this.anotherService = service;
            logger.info("Got anotherService. Thank you DS!");
        }
    }
    startWebserviceThread(publishingUrl);
}

在控制台输出中,我会看到来自setService的记录器消息,然后来自activate。始终使用默认值startWebserviceThread调用方法publishingUrl,而不是从ComponentContext属性文件获取的方法。

如果我在component.xml中设置immediate="true"immediate="false"

,也没有什么区别

运行时:Java 1.6,eclipse equinox

1 个答案:

答案 0 :(得分:3)

setService()方法用于将依赖项注入DS。 然后调用activate(),它就是工作线程应该开始的地方。

你必须移动startWebserviceThread(publishingUrl);在activate()方法的末尾。

您的逻辑也暗示了这一点。您可以从上下文中获取发布网址设置,然后就可以启动Web服务了。要使用其他服务,您需要在开始之前引用,因此这就是setService()之前调用activate()的原因。

this tutorial所述,不应在set / unset方法中使用服务。