I have a POJO that I'd like to inject into resources and filters:
public final class MyObject { }
I implemented a custom provider for it:
@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();
}
}
The object is successfully injected into my resource:
@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";
}
}
But Jersey fails to inject it into my filter:
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;
}
}
I'm guessing the difference has to do with the fact that in MyFilter
the injection is done using proxies that defer to thread-local instances - this is because the fields annotated with @Context
are declared in the outer class, which is instantiated once, but they are used to inject objects on a per-request basis. When I step through filter
during debugging, I can see that MyFilter.request
points to a proxy wrapping an instance of com.sun.jersey.server.impl.container.servlet.ThreadLocalInvoker
.
What is my custom provider (or implementation otherwise) missing that it needs to do custom injection into my filter?
Note that I'm currently stuck with Jersey 1.1.4.1 (sorry).
EDIT: Using Jersey 1.17, I get an exception at startup instead:
SEVERE: Missing dependency for field: private mypackage.MyObject mypackage.MyFilter.myObject