如何关闭代理的RESTEasy WebTarget

huangapple go评论71阅读模式
英文:

How to close a proxied RESTEasy WebTarget

问题

以下是翻译的内容:

给定以下的RESTEasy代码片段:

UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8080/movies");

ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
ResteasyWebTarget target = client.target(FULL_PATH);
MoviesResource proxy = target.proxy(MoviesResource.class);

Movie movie = proxy.movieById(someId);

我可以/可以/应该关闭 WebTargetClient 以释放我分配的资源。

然而,如果代理对象的创建以及其依赖关系都被交给一个类似如下的独立类:

public class Foo {
    private UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8080/movies");

    public MoviesResource getMoviesApi() {
        ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
        ResteasyWebTarget target = client.target(FULL_PATH);
        return target.proxy(MoviesResource.class);
    }
}

...

MoviesResource proxy = myFoo.getMoviesApi();
Movie movie = proxy.movieById(someId);
// A) 如何在这里清理资源?

如何关闭 `WebTarget``Client` 或它们的底层资源我无法通过代理实例访问它们中的任何一个如果我**关闭它们我会收到这个可怕的警告

> RESTEASY004687正在为您关闭类 org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine 的实例请自行关闭客户端

因此RESTEasy会为我清理资源但当然这不是我应该依赖的


<details>
<summary>英文:</summary>

Given the following RESTEasy snippet

    UriBuilder FULL_PATH = UriBuilder.fromPath(&quot;http://127.0.0.1:8080/movies&quot;);

    ResteasyClient client = (ResteasyClient)ClientBuilder.newClient();
    ResteasyWebTarget target = client.target(FULL_PATH);
    MoviesResource proxy = target.proxy(MoviesResource.class);

    Movie movie = proxy.movieById(someId);

I could/can/should close `WebTarget` or `Client` to free resources I allocated*.

However, what do I do if the creation of the proxy object and everything it depends on is handed off to a separate class like so:

    public class Foo {
        private UriBuilder FULL_PATH = UriBuilder.fromPath(&quot;http://127.0.0.1:8080/movies&quot;);
    
        public MoviesResource getMoviesApi() {
            ResteasyClient client = (ResteasyClient)ClientBuilder.newClient();
            ResteasyWebTarget target = client.target(FULL_PATH);
            return target.proxy(MoviesResource.class);
        }
    }

    ...

    MoviesResource proxy = myFoo.getMoviesApi();
    Movie movie = proxy.movieById(someId);
    // A) how to clean up here?

How do I close the `WebTarget` or `Client` or their underlying resources? I can&#39;t get access to either of them through the proxied instance.
If I do *not* close them I get this dreaded warning

&gt;  RESTEASY004687: Closing a class org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine instance for you. Please close clients yourself.

Hence, RESTEasy does clean up for me but that&#39;s of course not what I should rely on.

*there are discussions in a number of places eg. https://stackoverflow.com/q/33097230/131929 and https://stackoverflow.com/q/24700798/131929 about what is reusable and what not

</details>


# 答案1
**得分**: 0

感谢 @james-r-perkins 的反馈最终我得出了以下Kotlin代码

```kotlin
final inline fun <reified T : AutoCloseable> createServiceProxy(
    serviceName: String
): T = RestClientBuilder.newBuilder()
    .baseUri(createServiceUriBuilder(serviceName).build())
    .register(MyClientRequestFilter(appName, tokenProvider))
    .build(T::class.java)

与我早前的评论相反,RESTEasy MP RestClientBuilderImplQuarkus QuarkusRestClientBuilder 都创建了代理,而且这些代理也实现了 Closeable(它扩展了 AutoCloseable),正如 James 所说的...

然而,我们认为强制要求我们的客户端接口直接扩展 AutoCloseable 是有价值的。当然,这在源代码中会增加一些额外的字符,但从正面来看,这是编译器可以使用的类型信息,以便我们可以简化其他地方的代码。因此,在这里很重要的是泛型声明为 T : AutoCloseable 而不是 T : Any

英文:

Thanks to all the feedback from @james-r-perkins I eventually I arrived at the following (Kotlin) code:

final inline fun &lt;reified T : AutoCloseable&gt; createServiceProxy(
    serviceName: String
): T = RestClientBuilder.newBuilder()
    .baseUri(createServiceUriBuilder(serviceName).build())
    .register(MyClientRequestFilter(appName, tokenProvider))
    .build(T::class.java)

Contrary to my earlier comment both the RESTEasy MP RestClientBuilderImpl and the Quarkus QuarkusRestClientBuilder DO create proxies that also implement Closeable (which extends AutoCloseable). Just as James said...

However, we see value in enforcing that our client interfaces extend AutoCloseable directly. Sure, it's a few extra characters in the source code but on the plus-side it's type information the compiler can use to allow us to simplify code elsewhere. Hence, it's crucial here that the generics declaration is T : AutoCloseable rather than T : Any.

huangapple
  • 本文由 发表于 2023年2月18日 04:02:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488776.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定