0

次のサービスを公開するバンドル A があります。

OSGI-INF/config.xml 内

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
    name="com.example.MyService" modified="updated" immediate="true">
 <implementation class="com.example.impl.MyServiceImpl"/>
 <service>
  <provide interface="com.example.MyService"/>
 </service>
</scr:component>

次のステップでは、バンドル B のサーブレットからこのサービスを利用したいと考えています。

私がすることは次のとおりです。

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
 BundleContext bundleContext = (BundleContext) getServletContext().getAttribute("osgi-bundlecontext");
    if (bundleContext != null) {
     // Here MyService is the service exposed as declarative service
     MyService myService = getService(bundleContext, MyService.class);
     if(myService != null) {
      // I want to invoke some method declared in MyService interface
      myService.invokeMyServiceMethod();
     }
    }
}// end of doPost

protected <T> T getService(BundleContext bundleContext, Class<T> type) {
    ServiceReference<T> serviceRef = bundleContext.getServiceReference(type);
    if (serviceRef == null) {
        return null;
    }
    T service = bundleContext.getService(serviceRef);
    return service;
}// end of getService method

OSGi のサービスは行き来するので、doPost メソッドの非 null 参照のチェックに合格しても、次のステートメントmyService.invokeMyServiceMethod()は NPE をスローしないと想定するのは正しいですか?

サービス レジストリから MyService への有効な参照を常に取得することを保証するにはどうすればよいですか?

これが Http Service からサービス参照を取得する正しい方法でない場合、正しい方法はどれですか?

OSGi の実装として Equinox を使用しています。

乾杯、ボリス

4

1 に答える 1

2

宣言型サービス (DS) のいくつかを見逃していると思います :-) XML で依存関係を指定するという DS の全体的な考え方 (または注釈を使用すると、はるかに優れています)。サーブレットは次のようになります。

@Component(provide=Servlet.class)
public class MyServlet extends HttpServlet {
  T myService;

  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
    myService.invokeMyServiceMethod();
  }

  @Reference
  T setT(T t) {
    myService =t;
  }
}

必要なのは、Apache Felix の Http Whiteboard バンドルがインストールされていることを確認することだけです (はい、標準の美しさである Equinox で問題なく動作します)。このバンドルは、登録されているサーブレット サービスを監視し、それらを Http サービスに追加します。DS は、コンポーネントが myService を持つまでコンポーネントが登録されないようにするため、myService が null でないことが保証されます。これは DS 静的モードと呼ばれます。呼び出される前にすべての依存関係が満たされます。

勇気があれば、setTメソッドを動的に宣言できます。そうすれば、T サービスがなくてもコンポーネントが登録されます。たとえば、発信者にサービスがないことを伝えることができます。これを動的モードと呼びます。

使用される注釈は標準の DS です。それらは bnd によって処理され、XML に変換されます。これはmaven、gradleなどで機能しますが、もちろんbndtoolsで最も優れています。

于 2013-06-18T17:27:16.427 に答える