首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HK2:从子定位器访问RunLevel作用域服务

HK2:从子定位器访问RunLevel作用域服务
EN

Stack Overflow用户
提问于 2019-10-18 07:31:08
回答 2查看 283关注 0票数 1

我在Java应用程序中使用泽西。HK2向整个应用程序提供依赖注入。HK2 RunLevel服务在应用程序服务定位器中注册,应用程序服务定位器是Jerseys服务定位器的父服务器。

代码语言:javascript
复制
+ application locator
|\- RunLevel capabilities
| - MyCustomService, @RunLevel(value=1)
 \
  + jersey locator
   \- jersey resource class
     \ @Inject MyCustomService

我的问题是,我不能从泽西岛内访问运行级范围的服务。在上面的示例中,当打开泽西资源时,MyCustomService注入失败:

java.lang.IllegalStateException:找不到org.glassfish.hk2.runlevel.RunLevel的活动上下文

原因似乎是HK2 RunLevel特性背后的服务具有可见性本地:泽西定位器不能通过其父定位器访问它们。见这里

问题:

  • 为什么运行级功能的服务在可见性方面受到限制?
  • 我能做些什么来克服这个问题呢?

更新

为了给这个问题提供上下文,我使用了一种“System”风格的运行级。

  • Java应用程序启动。默认初始运行级别为-1,目标运行级别为3。在其实现的过程中,必须成功地通过不同的阶段才能继续。
  • 在运行级别1中,建立到依赖的外部应用程序(数据库、memcache、message等)的连接。
  • 在运行级别2中,启动用于后台处理和HTTP服务的ExecutorServices (运行泽西)。泽西拒绝此级别的所有传入请求。
  • 在运行级别3中,MessageListeners被附加到代理,向后台执行程序提供请求。泽西接受并处理HTTP请求。

这个概念允许对可用性和长时间运行的请求进行粒度控制。关闭时,应用程序将处于运行级2,直到完成先前接受的HTTP请求并完成排队的后台任务。但是,不接受任何新的任务/请求。然后,运行级别1,0,-1,退出。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-25 20:37:43

解决方案是尊重DescriptorVisibility#LOCAL,只从管理它们的服务定位器注入依赖于RunLevelContext的服务。

这有点麻烦:

  • 从泽西资源中,按名称获取具有运行级功能的服务定位器。
  • 让运行级作用域服务进行明确的注入。 ServiceLocatorFactory.getInstance().find("applicationLocator");applicationLocator = MyCustomService mcs = applicationLocator.getService(MyCustomService.class);mcs.doSomething();

为了减少忘记这样做的危险,并将MyCustomService注入到泽西资源中,我现在已经将我的运行级范围的服务标记为DescriptorVisibility#LOCAL。这样他们就不能被球衣定位仪注射。

票数 1
EN

Stack Overflow用户

发布于 2019-10-29 13:30:41

更新:这不起作用!

为了教育目的,我将把它留在这里,但是不这样做!一旦从jersey的服务定位器中访问了RunLevelController,就会丢失它在其他服务定位器上管理的所有服务的跟踪。

更新端

我已经用这个黑客解决了这个问题:我故意覆盖LOCAL可见性,并将所需的描述符插入到缺少它们的服务定位器中。

代码语言:javascript
复制
public class RunLevelBridge implements Feature {
    private final Logger log = LoggerFactory.getLogger(getClass());
    private final ServiceLocator sourceLocator;

    public RunLevelBridge(ServiceLocator sourceLocator) {
        this.sourceLocator = sourceLocator;
    }

    @Override
    public boolean configure(FeatureContext context) {
        if (sourceLocator == null) {
            log.error("Unable to bridge descriptors, the source service locator cannot be null");
            return false;
        }

        InjectionManager im = InjectionManagerProvider.getInjectionManager(context);
        ServiceLocator jerseyLocator = im.getInstance(ServiceLocator.class);
        if (jerseyLocator == null) {
            log.error("Unable to bridge descriptors, the target service locator cannot be null");
            return false;
        }

        if (!sourceLocator.equals(jerseyLocator.getParent())) {
            ExtrasUtilities.bridgeServiceLocator(jerseyLocator, sourceLocator);
            log.info("Bridge from {} into {} established", sourceLocator.getName(), jerseyLocator.getName());
        }

        Filter filter;
        filter = BuilderHelper.createContractFilter(RunLevelContext.class.getName());
        sourceLocator.getDescriptors(filter).forEach(
                (descriptor) -> ServiceLocatorUtilities.addOneDescriptor(
                        jerseyLocator, 
                        descriptor, 
                        false
                )
        );
        filter = BuilderHelper.createContractFilter(RunLevelController.class.getName());
        sourceLocator.getDescriptors(filter).forEach(
                (descriptor) -> ServiceLocatorUtilities.addOneDescriptor(
                        jerseyLocator, 
                        descriptor, 
                        false
                )
        );

        log.info("Added the RunLevel feature to jersey's service locator");
        return true;
    }

}

该桥已在ResourceConfig中注册

代码语言:javascript
复制
public class ApplicationConfig extends ResourceConfig {

    public ApplicationConfig(ServiceLocator parentLocator) {

        // bridge runlevel into jersey
        register(new RunLevelBridge(parentLocator));

        // ... other stuff ...

    }
}

我鼓励对这种非正统做法的反馈意见。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58445967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档