我有一个解决方案,它不需要DI容器,但仍然提供了大部分好处。
有两个部分。第一个是如何将实例放入@Context注入机制,而不是在 ApplicationConfig 对象中提供类。
以下是执行此操作的技术:
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);
}
}
你这样使用它:
webAppContext.addEventListener(
new CustomContextResteasyBootstrap()
.addContextObject(MyCustom.class, myCustom)
.addContextObject(AnotherCustom.class, anotherCustom)
// additional objects you wish to inject into the REST context here
);
现在,您可以将这些类与@Context注释一起使用:
@GET
public MyCustom echoService(@Context MyCustom custom) {
return custom;
}
谜题的下一部分是如何提供每个请求的上下文对象。为此,请在 jax-rs 调用层次结构顶部附近的某个位置添加以下代码(基本上,在此行下方调用的任何内容都将访问上下文对象):
ResteasyProviderFactory.pushContext(MyContextSpecific.class, new MyContextSpecific());
然后,您可以通过注入低于该级别的任意位置来引用此内容:
@GET
public String contextSpecificEchoService(@Context MyContextSpecific contextSpecific) {
return custom.toString();
}
这是穷人的DI,但它对于嵌入式休息服务器非常有效。