从Sling/CQ中的一个bundle获取OSGi服务

11

我正在使用Day CQ。我想使用Felix控制台中提供的连接池将一些数据存储在SQL Server DB中。我可以通过在defineObjects标签中定义类型为SlingScriptHelper的"sling"对象来在JSP中执行此操作。

sling.getService(DataSourcePool.class).

然而,我想使用在一个OSGi捆绑包中创建的Servlet来处理来自客户端的请求。该Servlet没有defineObjects标签,因此"sling"对象未定义。我没有看到在我的Servlet中创建有效的SlingScriptHelper对象的方法,但似乎这是可能的。

有一种方法吗?

3个回答

17

要从Java OSGi组件获取服务,您不需要使用SlingScriptHelper,您可以使用BundleContext.getService(...)方法,或者使用SCR注释让SCR将服务注入到您的组件中。

例如,您可以查看Sling的Slingbucks示例中一些组件如何使用SCR注释,例如ConfirmedOrdersObserver类以此方式获取SlingRepository:

   @Reference
   private SlingRepository repository;

请参见http://felix.apache.org/site/apache-felix-maven-scr-plugin.html,该Maven插件可处理这些注释。

我能够使用SCR注释方法。但是,我该如何获取BundleContext的实例呢?这是我无法解决的问题。 - joelt
我还没有测试过,但我认为可以使用activate()或者bind()方法来实现。 - joelt
2
在 activate(..) 和 deactivate(..) 中,需要一个 osgi ComponentContext 对象。从这个对象中,您可以派生出 BundleContext。但是,正如 Bertrand 所指出的那样,您不需要使用 bundle context 对象;您只需要在您的 servlet(即 Sling 服务)中使用 DCS 实例化您的对象即可。 - empire29
empire29是正确的,如果您使用SCR,您可以从activate/deactivate方法参数中获取BundleContext。当您使用SCR时,通常不需要BundleContext.getService(...),在大多数情况下,@Reference就足够了。 - Bertrand Delacretaz

9
您可以使用BundleContext通过调用#getServiceReference和#getService方法来获取服务。例如,如果您对ResourceResolverFactory感兴趣,可以按以下方式获取它:
BundleContext bundleContext = FrameworkUtil.getBundle(MyClass.class).getBundleContext();
ServiceReference factoryRef =
     bundleContext.getServiceReference(ResourceResolverFactory.class.getName());
ResourceResolverFactory resolverFactory = 
    (ResourceResolverFactory) bundleContext.getService(factoryRef);

我尝试使用@Reference注释将服务添加到我的bundle组件中。由于某种原因,引用为空。在我的bundle构造函数中使用上面的代码来显式获取服务解决了这个问题。谢谢 :) - Jeremy Grand-Scrutton
谢谢!@Reference 抛出了一个“资源不可修改错误”。这个方法有效! - Jakolcz

1
YourClass obj = this.getSlingScriptHelper().getService(yourclass.class);
obj.whatever();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接