1

宣言型 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>

マニフェスト.MF :

Service-Component: OSGI-INF/component.xml

サービスをインストールして開始した後、何も起こりませんでした。どうすればそれをアクティブにして、「Hello from PrintServiceImpl!」をコンソールに出力できますか。

4

6 に答える 6

3

バンドルの開始時にサービスを開始することを明示する必要があります。それ以外の場合は、遅延してインスタンス化され、他のサービスが PrintService を必要としない場合、まったくインスタンス化されません。

enabled属性とを使用して、(バンドルのライフサイクルに関して) サービスのライフサイクルを制御できますimmediateenabled些細なことです: バンドルの開始時にサービスが有効かどうかを示します。immediateこのサービスが遅延しているかどうかを示します。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">

Chris が述べたように、サービスがアクティブ化されたときに何かを実行したい場合は、activateライフサイクル メソッドにコードを追加する必要があります (上記で明示的に行われたように、コンポーネント記述子でメソッドの名前を指定できることに注意してください)。

protected final void activate() {
    print();
}
于 2012-06-14T12:27:20.533 に答える
2

なぜprintメソッドが呼び出されると思いますか?これはサービスのインターフェースの一部であるため、それにバインドして呼び出すクライアントができるようになるまで呼び出されません。

コンソールにコマンドを入力すると、バンドルがサービスservicesを公開していることがわかります。print.PrintServiceこれは、コンポーネントが機能していることを意味します。これが表示されない場合は、上記のコメントでTomSeidelが提案したSCRバンドルのようなものが欠落している可能性があります。

于 2012-06-13T11:08:28.077 に答える
1

おそらく、アクティブ化メソッドから印刷を実行したいですか?

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()メソッドを明示的に呼び出すクライアントが必要です。

于 2012-06-13T21:30:12.247 に答える
1

上記のすべての答えは正しいです。シェルに何かを印刷するようなものを作成するには、次のように記述できます。

public interface PrintService {
    public void print();
}

実装:

public class PrintServiceImpl implements PrintService {

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

コンポーネント.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>

これで、Command を使用して印刷メソッドを呼び出すことができます。

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>

Command Interface は Apache Felix Shell の一部です。Felix を実行helpしてコンソールに入力すると、登録されているすべてのコマンドが表示され、PrintCommand もありますprint。シェルで print と入力すると、テキストが表示されます。

于 2012-06-14T13:45:17.440 に答える