【问题标题】:How to consume OSGi service from OSGi HTTP Service如何从 OSGi HTTP 服务使用 OSGi 服务
【发布时间】:2013-06-14 07:49:42
【问题描述】:

我有一个包 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>

下一步,我想从 bundle B 中的一个 servlet 使用这个服务。

我要做的是:

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方法中的非空引用检查通过,下一条语句myService.invokeMyServiceMethod()也不会抛出NPE是否正确?

我如何保证我将始终从服务注册表中获得对 MyService 的有效引用?

如果这不是从 Http Service 获取服务引用的正确方法,那么正确的方法是什么?

我使用 Equinox 作为 OSGi 实现。

干杯, 鲍里斯

【问题讨论】:

    标签: osgi


    【解决方案1】:

    我认为您错过了一些声明性服务 (DS) :-) DS 的整个想法是您在 XML 中指定您的依赖项(或者使用注释更好)。 servlet 应该是这样的:

    @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 上运行良好,标准之美)。这个包监视任何正在注册的 Servlet 服务并将它们添加到 Http 服务中。由于 DS 确保您的组件在拥有 myService 之前不会注册,因此您的 myService 保证为非空。这称为 DS 静态模式:在调用之前,您的所有依赖项都已满足。

    如果你够勇敢,你可以将setT 方法声明为动态的。即使没有 T 服务,您的组件也会被注册。例如。允许您告诉呼叫者没有服务。这称为动态模式。

    使用的注释是标准的 DS。它们由 bnd 处理并转换为 XML。这适用于 maven、gradle 等,但最好的当然是 bndtools。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-09
      • 2019-09-02
      • 2015-07-20
      • 2014-08-24
      • 2010-10-02
      • 2013-08-26
      • 1970-01-01
      相关资源
      最近更新 更多