我有一个不需要 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,但它确实适用于嵌入式休息服务器。