声明OSGi服务(Declarative OSGi Services)

2019-09-29 10:50发布

我有一个关于声明的OSGi服务的问题。 我有以下接口:

  public interface PrintService {
    public void print();
  }

和它的实现:

    public class PrintServiceImpl implements PrintService {

      @Override
      public void print() {
        System.out.println("Hello from PrintServiceImpl!");
      }
    }

OSGI-INF / component.xml文件:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="service">
   <implementation class="service.PrintServiceImpl"/>
   <service>
      <provide interface="print.PrintService"/>
   </service>
</scr:component>

MANIFEST.MF:

Service-Component: OSGI-INF/component.xml

我安装服务并启动后,它没有happend。 如何激活它,并打印“ 从PrintServiceImpl你好!”来安慰。

Answer 1:

为什么你希望你的print要调用的方法? 这是服务的接口的一部分,所以它不会被调用,直到你可以结合到它,并调用它的客户端。

如果键入services控制台命令,你应该看到你的包被发布print.PrintService服务; 这意味着你的组件工作。 如果你没有看到这点,你可能会失去了一些东西,如SCR捆绑在上面的评论由汤姆·赛德尔的建议。



Answer 2:

你要明确你希望你服务时,束开始启动。 否则,将被懒洋洋地实例化,并给没有其他服务需要的PrintService,它不会在所有的实例。

您可以使用属性控制您的服务生命周期(相对于束生命周期) enabledimmediateenabled很简单:表示你的服务是否启用与否,当bundle启动。 immediate指示此服务是否偷懒OT没有。 immediate="true"立刻启动服务, immediate="false"将申请延迟实例(即等到其他一些服务请求该服务的依赖)

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="PrintService"
activate="activate" 
deactivate="deactivate"
modified="modified"
enabled="true" 
immediate="true">

正如克里斯提到的,如果你希望你的服务时,它的启动做一些事情,你应该添加一些代码到activate生命周期方法(注意:就像是上面明确做了该方法的名称可以在组件描述符中指定)

protected final void activate() {
    print();
}


Answer 3:

也许你想从您激活方法做打印?

public class PrintServiceImpl implements PrintService {
    protected final void activate() {
        System.out.println("Hello from PrintServiceImpl!");
    }
    protected final void deactivate() {
        System.out.println("Goodbye from PrintServiceImpl!");
    }
    ...
}

否则,尼尔的答案是正确的:你想它通过ServiceTracker的或使用该服务的客户端<reference>并明确调用print()方法。



Answer 4:

上述所有问题的答案是正确的。 我们有一些像你可以写类似的外壳印花的东西:

public interface PrintService {
    public void print();
}

Implentation:

public class PrintServiceImpl implements PrintService {

      @Override
      public void print() {
        System.out.println("Hello from PrintServiceImpl!");
      }
}

component.xml文件:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="service">
   <implementation class="service.PrintServiceImpl"/>
   <service>
      <provide interface="print.PrintService"/>
   </service>
</scr:component>

现在你可以使用一个命令来调用您的打印方法:

public class PrintCommand implements Command {

    private PrintService printer;

    public void setPrinter(PrintService printer) {
        this.printer = printer; 
    }

    public void unsetPrinter(PrintService printer) {
        this.printer = null;
    }

    @Override
    public void execute(String line, PrintStream arg1, PrintStream arg2) {    
        printer.print();
    }

    @Override
    public String getName() {
        return "print";
    }

    @Override
    public String getShortDescription() {
        return "just a printer";
    }

    @Override
    public String getUsage() {
        return "print";
    }

}

而你的component.xml文件应该有一个新的条目:

<component name="PrintCommand">
    <implementation class="PrintCommand"/>
    <service>
        <provide interface="org.apache.felix.shell.Command"/>
    </service>
    <reference
        name="printer"
        interface="PrintService"
        bind="setPrinter"
        unbind="unsetPrinter"
        cardinality="1..1"
        policy="static"
    />
</component>

命令接口是Apache的菲利克斯Shell的一部分,如果你现在运行菲利克斯和类型help在您的控制台,你会看到所有已注册的命令,并存在PrintCommand以及print 。 如果你现在在shell类型的打印,你会看到的文字。



Answer 5:

你有没有得到这个工作? 对我来说这是在Eclipse的.ds束只是还没有开始,因此该服务未注册(还)。 当我手动启动它在我的服务是正确注册。



文章来源: Declarative OSGi Services