Guice + Jersey 2 + ContainerRequestFilter 和 @Context

Guice + Jersey 2 + ContainerRequestFilter and @Context

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

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

所以我的 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 从未获得 created/run 我需要的所有依赖项。如果我使用 this.injector 或 this.authFilterProvider 那么我的 @Inject 字段是正确的,而我的 @Context 字段不是。我的理解是,这是因为我正在注册该对象的一个​​实例,因此 Jersey 无法管理 it/inject 它的 @Context 字段。但是,当我简单地注册 class 时,我的 @Context 字段已注册,但我的 @Inject 字段未注册。

我可以做什么 registration/injection 过程来确保 @Context 和 @Inject 在运行时都正确填充?

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

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

并且 MyResource 包含 @Context 成员和 @Inject 成员,@Context/@Inject 成员在运行时被正确填充。因此,出于某种原因,资源注册和过滤器 registration/management 的行为有所不同。

任何 ideas/insights 将不胜感激。

我想我可以在这里为您解答。

您是否使用@Provider 注释注册您的动态特征?

我相信这里可能发生的事情是 HK2 在您设置 Guice-HK2 Bridge 之前尝试注册您的 DynamicFeature(以及您的 Filter)。

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

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

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

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

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

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

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

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