Guice + Jersey 2 + ContainerRequestFilter和@Context

时间:2016-01-06 21:19:57

标签: java jersey guice jersey-2.0 dropwizard

我正在尝试使用Guice将依赖项注入通过ContainerRequestFilter注册的DynamicFeature。我还需要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成员在运行时都正确填充。因此,由于某种原因,资源注册和过滤器注册/管理的行为方式不同。

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

1 个答案:

答案 0 :(得分:2)

想想我可能会在这里找到答案。

您是否使用@Provider注释注册了dynamicFeature?

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

为了解决这个问题,我会尝试手动注册你的功能, 并从Feature / Filter类中删除@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。

相关问题