我正在尝试使用Guice将依赖项注入通过ContainerRequestFilter注册的DynamicFeature。我还需要Jersey来注入HttpServletRequest,我现在正试图通过@Context来做到这一点。这是一个Dropwizard应用程序。
我的最终目标是拥有一个通过DynamicFeature应用于特定资源的AuthenticationFilter。我的AuthenticationFilter有一些必须注入的依赖项,它还需要访问HttpServletRequest来完成它的工作。这是Dropwizard项目的一部分,该模式基于Dropwizard的AuthDynamicFeature和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永远不会创建/运行我需要的所有依赖项。如果我使用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成员在运行时都正确填充。因此,由于某种原因,资源注册和过滤器注册/管理的行为方式不同。
任何想法/见解将不胜感激。
答案 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。
我不知道为什么没有人遇到过这个问题,但似乎没有任何理由限制guice-bridge。