java Jersey端点+OSGi依赖项,跟踪
我有一个Jersey端点,它使用自定义OSGi服务ExceptionManager
服务
@Path("service")
public class ServiceFacade {
private volatile ExceptionManager exceptionManager;
public ServiceFacade() {
BundleContext bC = FrameworkUtil.getBundle(ServiceFacade.class).getBundleContext();
ServiceReference<ExceptionManager> sR = bC.getServiceReference(ExceptionManager.class);
if (sR != null)
this.exceptionManager = bC.getService(sR);
}
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces(MediaType.APPLICATION_JSON)
public Response sayHello() {
try {
if (exceptionManager == null)
return Response.status(Status.SERVICE_UNAVAILABLE).build();
// Do some work...
} catch (Exception e) {
exceptionManager.handle(e);
}
}
}
Jersey类作为一个简单类添加到Jersey应用程序中,这意味着每次用户点击该端点时,都会创建该类的一个新实例来处理该请求。如您所见,该类包含一个初始化ExceptionManager
服务的构造函数。我的问题是,没有一种简单的方法可以在不去BundleContext
的情况下检索服务吗
我已经看到了DependencyManager
,但是这个捆绑包似乎只在激活过程中将依赖项添加到类中(ServiceFacade
,在本例中),但是依赖项解析太早了,这必须在运行时完成,每次创建一个实例。Bellow是DependencyManager
的近似值,但不是此问题的解决方案:
public class Activator extends DependencyActivatorBase {
@Override
public void init(BundleContext bundleContext, DependencyManager dependencyManager) throws Exception {
dependencyManager.add(createComponent()
.setImplementation(ServiceFacade.class)
.add(createServiceDependency()
.setService(ExceptionManager.class)
.setRequired(true));
}
}
谢谢-
# 1 楼答案
您可以通过使用声明性服务获得对OSGi服务的引用,而无需访问BundleContextA tutorial can be found here
# 2 楼答案
可以将端点设为singleton resource。通过这种方式,您可以让依赖关系管理器创建单个实例并注入服务,然后将该实例添加到Jersey应用程序中
有一些限制,比如Jersey的字段或构造函数注入不起作用。在使用资源字段时,还必须注意并发性