如何从OSGiHTTP服务使用OSGi服务

如何从OSGiHTTP服务使用OSGi服务,osgi,Osgi,我有一个包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

我有一个包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
protectedvoid-doPost(HttpServletRequest-req,HttpServletResponse-resp)抛出ServletException{
BundleContext BundleContext=(BundleContext)getServletContext().getAttribute(“osgi BundleContext”);
if(bundleContext!=null){
//这里MyService是作为声明性服务公开的服务
MyService MyService=getService(bundleContext,MyService.class);
if(myService!=null){
//我想调用MyService接口中声明的一些方法
myService.invokeMyServiceMethod();
}
}
}//doPost结束
受保护的T getService(BundleContext BundleContext,类类型){
ServiceReference serviceRef=bundleContext.getServiceReference(类型);
if(serviceRef==null){
返回null;
}
T service=bundleContext.getService(serviceRef);
回程服务;
}//服务结束方法
当OSGi中的服务来来往往时,假设即使doPost方法中的非空引用检查通过,下一条语句myService.invokeMyServiceMethod()也不会抛出NPE,这是否正确

我如何保证总是从服务注册中心获得对MyService的有效引用

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

我使用Equinox作为OSGi实现

干杯,
Boris

我认为您错过了一些声明性服务(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;
  }
}
唯一需要做的是确保安装了ApacheFelix的Http白板包(是的,它在Equinox上工作得很好,标准之美)。此捆绑包监视正在注册的任何Servlet服务,并将它们添加到Http服务中。由于DS确保组件在拥有myService之前不会注册,因此myService保证为非null。这称为DS静态模式:在调用之前,您的所有依赖项都已满足

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

使用的注释是标准的DS。它们由bnd处理并转换为XML。这在maven、gradle等中有效,但在bndtools中效果最好