我有一个关于声明的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你好!”来安慰。
为什么你希望你的print
要调用的方法? 这是服务的接口的一部分,所以它不会被调用,直到你可以结合到它,并调用它的客户端。
如果键入services
控制台命令,你应该看到你的包被发布print.PrintService
服务; 这意味着你的组件工作。 如果你没有看到这点,你可能会失去了一些东西,如SCR捆绑在上面的评论由汤姆·赛德尔的建议。
你要明确你希望你服务时,束开始启动。 否则,将被懒洋洋地实例化,并给没有其他服务需要的PrintService,它不会在所有的实例。
您可以使用属性控制您的服务生命周期(相对于束生命周期) enabled
和immediate
。 enabled
很简单:表示你的服务是否启用与否,当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();
}
也许你想从您激活方法做打印?
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()方法。
上述所有问题的答案是正确的。 我们有一些像你可以写类似的外壳印花的东西:
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类型的打印,你会看到的文字。
你有没有得到这个工作? 对我来说这是在Eclipse的.ds束只是还没有开始,因此该服务未注册(还)。 当我手动启动它在我的服务是正确注册。