如何正确共享JAX-RS 2.0客户端

时间:2016-01-02 13:11:40

标签: rest java-ee rest-client

为我的问题提供一点背景......

我有一个Java EE Web应用程序(作为UI /客户端),它使用JAX-RS 2.0客户端API(Resteasy实现)通过REST接口访问数据/业务逻辑服务。

目前,我使用RequestScoped CDI托管bean为每个请求注入一个新的JAXRS客户端实例,其思想是客户端应用程序可以为每个请求调用多个后端资源,并且我为整个请求重用相同的JAXRS客户端(尽管我在某处阅读这可能不正确,因为我可能会更改每个调用的URI)

JAXRS Client的文档似乎表明客户端是一个可能很昂贵的操作,应用程序应该限制它创建的连接数量。它似乎也自相矛盾,并建议在完成对特定WebTarget的所有请求后,客户端应该关闭。

客户端应用程序可能会支持数千个并发用户,因此创建和销毁数千个“昂贵的客户端”似乎不是正确的方法所以我认为共享客户端池更合适但似乎没有有关如何实现这一目标的信息。

所有示例似乎都显示为请求创建了一个新客户端,a)在关闭之后关闭它,或者b)没有关闭它,但没有真正解释第二个请求会发生什么。

您能否就如何解决这一问题提供一些答案,或者提供有关此方法最佳实践的信息。

感谢。

1 个答案:

答案 0 :(得分:11)

唯一的"最佳实践"建议我seen避免使用JAX-RS 2.0客户端的性能不佳或内存使用不良模式与Jersey的Jax-RS实现有关,因此它可能对RestEasy无效。但是,我怀疑这两个实现是相似的,建议是可移植的。

基本上,我的理解是

  • 使用ClientBuilder创建少量完全配置的客户端实例 - 在不同情况下,您可能需要具有不同配置的不同客户端(例如,序列化/反序列化提供程序)。这类事情应该围绕应用程序初始化或类似的“稀有”类型进行。事件。
  • 在具有相同配置要求的类之间共享每个完全配置的客户端实例。例如,您可以告诉您的DI框架将每个客户端实例的范围限定为@Singleton
  • 避免调用修改底层配置的客户端实例上的任何方法。例如register(Class<T> componentClass)之类的东西 - 几乎javax.ws.rs.core.Configurable界面上的任何内容。
  • 使用共享客户端的每个实例对象都可以(并且应该?)创建自己的私有和非共享WebTargets。实际上,它的WebTargets应该是@RequestScoped而不是客户。
  • 但是,与Client一样,使用WebTarget的任何内容都应避免通过javax.ws.rs.core.Configurable接口方法进行任何操作。

之后,它几乎一帆风顺。