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 以使用正常可见性。
我不知道为什么没有人 运行 进入这个问题,但它似乎无缘无故地限制了 guice-bridge。
我正在尝试使用 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 以使用正常可见性。
我不知道为什么没有人 运行 进入这个问题,但它似乎无缘无故地限制了 guice-bridge。