I've got a solution to this that doesn't require a DI container, but still gives most of the benefit.
There's two parts. The first is how to get instances into the @Context injection mechanism instead of providing classes in the ApplicationConfig object.
Here's a technique for doing that:
private static class CustomContextResteasyBootstrap extends org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap{
private final Map<Class<?>, Object> additionalContextObjects = new HashMap<Class<?>, Object>();
public <E> CustomContextResteasyBootstrap addContextObject(Class<? super E> clazz, E obj){
additionalContextObjects.put(clazz, obj);
return this;
}
@Override
public void contextInitialized(ServletContextEvent event) {
super.contextInitialized(event);
deployment.getDispatcher().getDefaultContextObjects().putAll(additionalContextObjects);
}
}
and you use it like this:
webAppContext.addEventListener(
new CustomContextResteasyBootstrap()
.addContextObject(MyCustom.class, myCustom)
.addContextObject(AnotherCustom.class, anotherCustom)
// additional objects you wish to inject into the REST context here
);
now you can use those classes with the @Context annotation:
@GET
public MyCustom echoService(@Context MyCustom custom) {
return custom;
}
The next part of the puzzle is how to provide per-request context objects. To do this, add the following code somewhere near the top of the jax-rs call hierarchy (basically, anything that gets called below this line will get access to the context object):
ResteasyProviderFactory.pushContext(MyContextSpecific.class, new MyContextSpecific());
You can then reference this via injection anywhere below that level:
@GET
public String contextSpecificEchoService(@Context MyContextSpecific contextSpecific) {
return custom.toString();
}
This is poor-man's DI, but it works really well for embedded rest servers.