Guice + Jersey 2 + ContainerRequestFilter和@Context [英] Guice + Jersey 2 + ContainerRequestFilter and @Context

查看:63
本文介绍了Guice + Jersey 2 + ContainerRequestFilter和@Context的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Guice将依赖项注入

I'm attempting to use Guice to inject dependencies into a ContainerRequestFilter that is being registered via a DynamicFeature. I also need Jersey to inject the HttpServletRequest and I am currently attempting to do this via @Context. This is in a Dropwizard app.

我的最终目标是拥有一个通过DynamicFeature应用于特定资源的AuthenticationFilter.我的AuthenticationFilter有一些必须注入的依赖项,它还需要访问HttpServletRequest来完成其工作.这是Dropwizard项目的一部分,该模式基于Dropwizard的 AuthDynamicFeature

My end goal is to have an AuthenticationFilter that is applied to specific Resources via a DynamicFeature. My AuthenticationFilter has a few dependencies that must be injected and it also needs access to the HttpServletRequest to do its job. This is part of a Dropwizard project and the pattern is based on Dropwizard's AuthDynamicFeature and AuthFilter but modified to support injection.

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

So my AuthenicationFilter looks like this:

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看起来像这样:

And my DynamicFeature looks like this:

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字段.

Unfortunately my AuthFilter never gets created/run with all of the dependencies that I need. If I use this.injector or this.authFilterProvider then my @Inject fields are correct by my @Context fields are not. My understanding is that this is because I'm registering an instance of the object and thus Jersey cannot manage it/inject it's @Context fields. However when I simply register the class my @Context fields are registered but my @Inject fields are not.

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

What registration/injection process can I do to ensure that both @Context and @Inject are properly filled at runtime?

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

One other piece of information potentially useful information: if I register a resource with the following line:

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

并且MyResource包含@Context成员和@Inject成员,两个@ Context/@ Inject成员在运行时都已正确填充.因此,出于某种原因,资源注册和筛选器注册/管理的行为有所不同.

And MyResource contains @Context members and @Inject members both the @Context/@Inject members are filled properly at runtime. So for some reason the Resource registration and Filter registration/management are behaving differently.

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

Any ideas/insights would be greatly appreciated.

推荐答案

我想这里可能有一个答案.

Think i may have an answer here for you.

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

Are you registering your dynamicFeature with an @Provider annotation?

我相信这里可能发生的事情是HK2尝试在设置Guice-HK2桥之前注册您的DynamicFeature(并因此注册您的过滤器).

I believe what could be happening here is that HK2 attempts to register your DynamicFeature, (and thus your Filter), before you have setup the Guice-HK2 Bridge.

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

In order to work around this, i would attempt manually registering your feature, and remove the @Provider annotation from your Feature/Filter classes.

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

如果实际可行,我将在稍后进行更新.

I will update this later if it actually works.

-编辑- 以上是完全错误的 之所以无法在ContainerRequestFilter中看到guice依赖关系,是因为GuiceScope类的可见性是LOCAL.

--EDIT -- was completely wrong w/ above The reason why you are unable to see your guice dependencies in ContainerRequestFilter is because the visiblity of the GuiceScope class is LOCAL.

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

This basically means that only the parent serviceLocator will be able to correctly service guice dependencies. ContainerRequestFilter/Mappers/Features are all created by child serviceLocators, and thus do not have access to resolve the GuiceScope context.

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

In order to fix this I have forked hk2 guice-bridge and rewritten GuiceScope to use visibility NORMAL.

这里是代码的链接:我不知道为什么没有人遇到这个问题,但是似乎没有充分的理由限制了guice-bridge.

I don't know why anyone hasn't run into this issue, but it seems to limit the guice-bridge for no good reason.

这篇关于Guice + Jersey 2 + ContainerRequestFilter和@Context的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆