java自定义提供程序无法插入到筛选器中
我有一个POJO,我想将其注入到资源和过滤器中:
public final class MyObject { }
我为它实现了一个自定义提供程序:
@Provider
public final class MyProvider
extends AbstractHttpContextInjectable<MyObject>
implements InjectableProvider<Context, Type> {
@Context private HttpServletRequest request;
@Override
public Injectable<MyObject> getInjectable(
ComponentContext componentContext,
Context annotation,
Type type
) {
if (type.equals(MyObject.class)) {
return this;
}
return null;
}
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
@Override
public MyObject getValue(HttpContext httpContext) {
//in reality, use session info from injected request to create MyObject
return new MyObject();
}
}
对象已成功注入我的资源:
@Path("/test")
@ResourceFilters(MyFilter.class)
public final class MyResource {
@Context private HttpServletRequest request;
@Context private MyObject myObject;
@GET
public String execute() {
System.out.println(request != null); //true
System.out.println(myObject != null); //true
return "data";
}
}
但Jersey未能将其注入我的过滤器:
public final class MyFilter implements ResourceFilter {
@Context private HttpServletRequest request;
@Context private MyObject myObject;
@Override
public ContainerRequestFilter getRequestFilter() {
return new ContainerRequestFilter() {
@Override
public ContainerRequest filter(ContainerRequest containerRequest) {
System.out.println(request != null); //true
System.out.println(myObject != null); //false
return containerRequest;
}
};
}
@Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
}
我猜区别在于MyFilter
中的注入是使用遵从线程本地实例的代理完成的,这是因为@Context
注释的字段在外部类中声明,外部类实例化一次,但它们用于根据每个请求注入对象。在调试期间,当我单步通过filter
时,我可以看到MyFilter.request
指向一个包装com.sun.jersey.server.impl.container.servlet.ThreadLocalInvoker
实例的代理
我的自定义提供程序(或实现)缺少什么,需要在我的过滤器中进行自定义注入
请注意,我目前只能使用Jersey 1.1.4.1(抱歉)
编辑:使用Jersey 1.17,我在启动时会出现异常:
SEVERE: Missing dependency for field: private mypackage.MyObject mypackage.MyFilter.myObject
# 1 楼答案
我从JSR-311找到了一个使用^{} 可注入接口的解决方法。首先,我必须让我的提供者实现^{} :
然后我将一个
Providers
实例注入到我的过滤器中。调用filter
时,我使用它查找ContextResolver
中的MyObject
并动态检索它:多亏了this answer向我透露了
Providers
的消息。这个解决方案是可行的,但它并不漂亮。我仍然希望在任何地方注入MyObject
,然后让它工作,就像HttpServletRequest
-我想知道我的提供者缺少什么,需要它来实现这一点# 2 楼答案
我在尝试实现相同的目标时遇到了这个问题(即,注入由自定义提供程序实现提供的内容),并发现如果您使用过滤器工厂,自定义注入可以很好地工作
因此,不要将@Context MyClass myObj注释放入过滤器类,而是在负责创建过滤器的过滤器工厂中放置该类型的带注释字段,并将工厂传递“myObj”作为常规参数
我不确定这对您的情况是否有帮助,而且我还没有调查过将此用于每个请求提供程序(我的是单例范围的)的含义,所以YMMV