JAX-RS (Apache CXF) 通过 setter 进行上下文注入

JAX-RS (Apache CXF) Context injection via setter

我正在尝试通过 Kotlin 中的 @Context 注释将 HttpServletRequest 注入我的 JAX-RS 资源(Apache CXF 实现)。如果我通过方法参数注入它,它工作正常。但是我不想 "mess" 我的接口,所以我想通过 field/setter.

注入它

普通字段注入的问题是代理的名称中包含 $,这对 kotlin 来说是个问题,因为它无法使用名称中包含美元的 class 名称。

所以我正在尝试使用这个简单的方法通过 setter 来完成:

var req : HttpServletRequest? = null

Context
fun setRequest(req : HttpServletRequest) {
    this.req = req
}

问题是(我相信这也应该是 Java 中的一个问题),setter 是通过 org.apache.cxf.jaxrs.utils.InjectionUtils 中抛出 java.lang.IllegalArgumentException 的方法 injectThroughMethod 中的反射调用的:对象不是声明 class

的实例

我尝试 google 这个问题,但没有成功。有没有人有类似的问题或者我做错了什么?

顺便说一下,我还在 CXF 的 JIRA 中创建了一个 issue

感谢评论 CXF Jira 问题的人,我设法解决了这个问题。 要使 setter 注入与 CXF 一起工作,您还必须在您的界面中定义 setter(不仅是在实现 class 时),并在那里(在界面上)用 @Context 对其进行注释。我不确定这是否真的符合规范,但 CXF 似乎要求这样。

像这样:

public MyInterface {
   @Context
   public void setRequest(HttpServletRequest req);
}

public MyClass implements MyInterface {
   private HttpServletRequest req;

   public void setRequest(HttpServletRequest req) {
      this.req = req;
   }
}

来自 CXF Jira 的 Sergey 的解释是:

This is not a standard specific issue, it is all down to the fact that the service object provided to the runtime is a proxy, and moving the setter to the interface ensures that this setter is part of the proxy. In my tests I do not have these setters on the main interface representing the service but on the the dedicated interface like Injectable.Alternatively, with Spring at least, enabling Cglib proxy mode can help.