【问题标题】:Guice + Jersey 2 + ContainerRequestFilter and @ContextGuice + Jersey 2 + ContainerRequestFilter 和 @Context
【发布时间】:2016-04-11 03:00:42
【问题描述】:

我正在尝试使用 Guice 将依赖项注入通过 DynamicFeature 注册的 ContainerRequestFilter。我还需要 Jersey 来注入 HttpServletRequest,我目前正在尝试通过 @Context 执行此操作。这是在 Dropwizard 应用程序中。

我的最终目标是拥有一个通过 DynamicFeature 应用于特定资源的 AuthenticationFilter。我的 AuthenticationFilter 有一些必须注入的依赖项,它还需要访问 HttpServletRequest 才能完成工作。这是 Dropwizard 项目的一部分,该模式基于 Dropwizard 的 AuthDynamicFeatureAuthFilter,但经过修改以支持注入。

所以我的 AuthenicationFilter 看起来像这样:

public class AuthFilter implements ContainerRequestFilter {

    @Context
    private HttpServletRequest httpServletRequest;

    @Context
    private HttpServletResponse httpServletResponse;

    @Inject
    private InjectableResource injectableResource;

    public void filter(ContainerRequestContext requestContext) throws IOException {

       // Do Auth
    }
}

我的 DynamicFeature 看起来像这样:

public class InjectableAuthDynamicFeature implements DynamicFeature {

    // Have tried multiple methods to register fitlers: using Injector,
    // using Provider and using the normal Class
    @Inject
    private Provider<AuthFilter> authFilterProvider;

    @Inject
    private Injector injector;

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {

        // Logic to decide on registering of filter followed by one of the
        // following depending on injection method:

        context.register(AuthFilter.class);
        context.register(this.injector.getInstance(AuthFilter.class);
        context.register(this.authFilterProvider.get());
    }
}

不幸的是,我的 AuthFilter 从未使用我需要的所有依赖项创建/运行。如果我使用 this.injector 或 this.authFilterProvider ,那么我的 @Inject 字段是正确的,而我的 @Context 字段不正确。我的理解是,这是因为我正在注册对象的一个​​实例,因此 Jersey 无法管理它/注入它的 @Context 字段。但是,当我只是注册课程时,我的 @Context 字段已注册,但我的 @Inject 字段未注册。

我可以做哪些注册/注入过程来确保@Context和@Inject在运行时都被正确填充?

另一条信息可能有用的信息:如果我使用以下行注册资源:

// AKA Dropwizard environment.jersey().register(...);
resourceConfig.register(this.injector.getInstance(MyResource.class));

MyResource 包含@Context 成员和@Inject 成员,@Context/@Inject 成员都在运行时正确填充。因此,由于某种原因,资源注册和过滤器注册/管理的行为不同。

任何想法/见解将不胜感激。

【问题讨论】:

  • 同样的问题 - 你找到方法了吗?

标签: java jersey guice jersey-2.0 dropwizard


【解决方案1】:

我想我可能会在这里为您提供答案。

您是否正在使用 @Provider 注释注册您的 dynamicFeature?

我相信这里可能发生的情况是 HK2 在您设置 Guice-HK2 桥之前尝试注册您的 DynamicFeature(以及您的过滤器)。

为了解决这个问题,我会尝试手动注册您的功能, 并从您的功能/过滤器类中删除 @Provider 注释。

// do your hk2 guice-bridge stuff before this
resourceConfig.register(InjectableAuthDynamicFeature.class)

如果它确实有效,我稍后会更新它。

--编辑-- 以上是完全错误的 您无法在 ContainerRequestFilter 中看到您的 guice 依赖项的原因是因为 GuiceScope 类的可见性是 LOCAL。

这基本上意味着只有父 serviceLocator 才能正确地服务 guice 依赖项。 ContainerRequestFilter/Mappers/Features 都是由子 serviceLocators 创建的,因此无权解析 GuiceScope 上下文。

为了解决这个问题,我分叉了 hk2 guice-bridge 并重写了 GuiceScope 以使用可见性 NORMAL。

这里是代码链接:https://github.com/hk2-project/hk2/blob/master/guice-bridge/src/main/java/org/jvnet/hk2/guice/bridge/internal/GuiceScopeContext.java#L58

我不知道为什么没有人遇到这个问题,但它似乎无缘无故地限制了 guice-bridge。

【讨论】:

  • 我遇到了类似的问题。我最终在我的过滤器中使用了@Context 注释。
  • 我查看了 guice-bridge 的 git 历史。添加 @Visibility(DescriptorVisibility.LOCAL) 的提交说“所有其他上下文都在本地避免子定位器内存泄漏”。也许这只是桥的限制。
猜你喜欢
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多