响应请求后,Java 变量值保留在内存中

问题描述

我将使用 this docker 映像部署 Java 应用程序。我试图消除即使在生成响应后变量的值仍然存在的问题。我的假设是每个请求都有一个独立的环境,但我不确定是否正确。

例如,下面给定的代码块会将给定的 URL 参数添加一个虚拟列表中。

@Path("/hello")
public class GreetingResource {

    private final List<String> dummyList = new ArrayList<>();

    @GET
    @Path("/{param}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response hello(@PathParam("param") String param) throws InterruptedException {
        dummyList.add(param);
        
        return Response.ok(dummyList.toString()).build();
    }
}

如果你像这样卷曲端点两次:

/hello/client1
/hello/client2

我的期望是:

[client1]
[client2]

但我实际上得到的是:

[client1]
[client1,client2]

这会让我有点担心并发会话,问题是我该如何解决

解决方法

这是为什么:

private final List<String> dummyList = new ArrayList<>();

根据经验:Never keep instance variables 在服务类中。尽可能使用 DTO 和值对象来维护状态。在构建面向服务的架构方面,您所拥有的东西是一个很大的禁忌。

具体来说,对于这种情况,Quarkus 将服务类 (GreetingResources) 的范围默认为单例范围,这意味着将使用单个实例来处理所有请求。

您可以通过在配置中配置 quarkus.resteasy.singleton-resources 属性来更改此行为。

,

如果你想在每次方法调用后都有一个干净的响应,你可以尝试在方法内部声明数组列表。

@GET
@Path("/{param}")
@Produces(MediaType.APPLICATION_JSON)
public Response hello(@PathParam("param") String param) throws InterruptedException {
    List<String> dummyList = new ArrayList<>();
    dummyList.add(param);
    
    return Response.ok(dummyList.toString()).build();
}
,

您有一个 GreetingResource 类(单例)实例处理您的所有请求。他们将分享你定义了实例变量在类像F.X. dummyList

如果你需要具有范围请求的东西,你可以注入一个具有范围请求的 bean,比如 f.x。

@Bean
@RequestScope
public HelloMessageGenerator requestScopedBean() {
    return new HelloMessageGenerator();
}

此实例是来自https://www.baeldung.com/spring-bean-scopes

您可能要移动dummyList您的hello方法内是否会为你工作。

如果这不能解决您的问题,如果您能向我们提供一些有关您为何需要此 dummyList 变量的信息,将会很有帮助。